|
作為一個(gè)社區(qū)類型軟件,大并發(fā)支持和高效穩(wěn)定運(yùn)行永遠(yuǎn)是“硬道理”,而有效安全的使用緩存恰恰能起到事倍功半的效果。而.NET本身所提供的緩存機(jī)制又顯得過(guò)于“單薄”,比如說(shuō)訂制不太靈活方便, 緩存對(duì)象之間層次感不強(qiáng), 使用時(shí)缺乏統(tǒng)一的管理等等。
Discuz!NT緩存產(chǎn)生背景:
在去年五月份我加入Discuz!NT項(xiàng)目組時(shí),發(fā)現(xiàn)這個(gè)項(xiàng)目當(dāng)時(shí)還未使用緩存機(jī)制。主要原因是項(xiàng)目還處于起步階段,很多東西還只是有想法,但未付諸實(shí)施,或還沒(méi)找到合適的方案, 而緩存就是其中一個(gè)到底該不該使用,如果使用的該到底能多大程度緩解數(shù)據(jù)庫(kù)壓力以及開(kāi)發(fā)成本的東西。
我當(dāng)時(shí)正好有一個(gè)比較好的“原型”(從一本書(shū)上看到的源碼),也就是今天Discuz!NT所使用的緩存機(jī)制的雛形,但當(dāng)時(shí)它在功能上還很不健全且存在一些“致命的” BUG, 但實(shí)現(xiàn)簡(jiǎn)單的緩存數(shù)據(jù)對(duì)象還是綽綽有余的,于是我通過(guò)一個(gè)簡(jiǎn)單的測(cè)試用例(緩存數(shù)據(jù)表和StringBuilder對(duì)象)和雪人一起討論并分析后得到一些數(shù)據(jù),基本上肯定了使用緩存解決對(duì)數(shù)據(jù)庫(kù)象中經(jīng)常訪問(wèn)但又不經(jīng)常更新的數(shù)據(jù)進(jìn)行緩存的使用方案,同時(shí)也要求這個(gè)緩存機(jī)制要使用起來(lái)盡可能的簡(jiǎn)單,同時(shí)功能擴(kuò)展要非常方便。
因此本人就在這個(gè)“原型”的基本上進(jìn)行了一段時(shí)間的功能擴(kuò)展和BUG修正才得到今天大家所看到的這部分代碼。
現(xiàn)在將Discuz!NT的緩存架構(gòu)說(shuō)明如下,先請(qǐng)大家看一下Discuz!NT架構(gòu)圖:
其實(shí)這個(gè)構(gòu)架說(shuō)白了就是一個(gè)標(biāo)準(zhǔn)的“策略”模式,為了對(duì)比方便,我把策略模式的結(jié)構(gòu)圖放在下面:
里面的DNTCache就是“策略”模式的應(yīng)用場(chǎng)景,而DefaultCache , ForumCache,RssCache等等就是相應(yīng)的具體策略,每一種策略都會(huì)對(duì).NET所提供的緩存機(jī)制進(jìn)行一番“訂制”,以實(shí)現(xiàn)不同的用途。比如系統(tǒng)DefaultCache在對(duì)象到期時(shí)提供數(shù)據(jù)再次加載機(jī)制,而ForumCache不使用這種機(jī)制,另外還有緩存的到期時(shí)間幾種策略也各不相同,這都是根據(jù)具體的應(yīng)用場(chǎng)景"量身訂制"的。
說(shuō)到這里,您所要做的就是下載一份源碼按上圖索驥就可以把整個(gè)緩存機(jī)制搞清楚。
下面對(duì)緩存設(shè)計(jì)所采用的幾種技術(shù)做一下簡(jiǎn)要說(shuō)明。包括XML,XPATH ,"單件模式" 以及跨web園共享數(shù)據(jù)。
首先請(qǐng)看一下代碼:(xml xpath)
2 //要緩存的對(duì)象


3 public virtual void AddObject(string xpath, object o ,string[] files)
4 {
5


6 //整理XPATH表達(dá)式信息
7 string newXpath = PrepareXpath(xpath);
8 int separator = newXpath.LastIndexOf("/");
9 //找到相關(guān)的組名
10 string group = newXpath.Substring(0,separator );
11 //找到相關(guān)的對(duì)象
12 string element = newXpath.Substring(separator + 1);
13
14 XmlNode groupNode = objectXmlMap.SelectSingleNode(group);
15 //建立對(duì)象的唯一鍵值, 用以映射XML和緩存對(duì)象的鍵
16 string objectId="";
17
18 XmlNode node = objectXmlMap.SelectSingleNode(PrepareXpath(xpath));
19 if ( node != null)
20 {
21 objectId = node.Attributes["objectId"].Value;
22 }
23 if(objectId=="")
24 {
25 groupNode = CreateNode(group);
26 objectId= Guid.NewGuid().ToString();
27 //建立新元素和一個(gè)屬性 for this perticular object
28 XmlElement objectElement = objectXmlMap.OwnerDocument.CreateElement(element);
29 XmlAttribute objectAttribute =objectXmlMap.OwnerDocument.CreateAttribute("objectId");
30 objectAttribute.Value = objectId;
31 objectElement.Attributes.Append(objectAttribute);
32 //為XML文檔建立新元素
33 groupNode.AppendChild(objectElement);
34 }
35 else
36 {
37 //建立新元素和一個(gè)屬性 for this perticular object
38 XmlElement objectElement = objectXmlMap.OwnerDocument.CreateElement(element);
39 XmlAttribute objectAttribute =objectXmlMap.OwnerDocument.CreateAttribute("objectId");
40 objectAttribute.Value = objectId;
41 objectElement.Attributes.Append(objectAttribute);
42 //為XML文檔建立新元素
43 groupNode.ReplaceChild(objectElement,node);
44 }
45 //向緩存加入新的對(duì)象
46 cs.AddObjectWithFileChange(objectId,o,files);
47


48 }
49
NET技術(shù):Discuz!NT 緩存設(shè)計(jì)簡(jiǎn)析 [原創(chuàng)],轉(zhuǎn)載需保留來(lái)源!
鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請(qǐng)第一時(shí)間聯(lián)系我們修改或刪除,多謝。