Discuz!NT 缓存设计简析 [原创]

       作为一个社区类型软件,大并发支持和高效稳定运行永远是“硬道理”,而有效安全的使用缓存恰恰能起到事倍功半的效果。而.NET本身所提供的缓存机制又显得过于“单薄”,比如说订制不太灵活方便, 缓存对象之间层次感不强, 使用时缺乏统一的管理等等。   
       Discuz!NT缓存产生背景:
       在去年五月份我加入Discuz!NT项目组时,发现这个项目当时还未使用缓存机制。主要原因是项目还处于起步阶段,很多东西还只是有想法,但未付诸实施,或还没找到合适的方案, 而缓存就是其中一个到底该不该使用,如果使用的该到底能多大程度缓解数据库压力以及开发成本的东西。
       我当时正好有一个比较好的“原型”(从一本书上看到的源码),也就是今天Discuz!NT所使用的缓存机制的雏形,但当时它在功能上还很不健全且存在一些“致命的” BUG, 但实现简单的缓存数据对象还是绰绰有余的,于是我通过一个简单的测试用例(缓存数据表和StringBuilder对象)和雪人一起讨论并分析后得到一些数据,基本上肯定了使用缓存解决对数据库象中经常访问但又不经常更新的数据进行缓存的使用方案,同时也要求这个缓存机制要使用起来尽可能的简单,同时功能扩展要非常方便。
       因此本人就在这个“原型”的基本上进行了一段时间的功能扩展和BUG修正才得到今天大家所看到的这部分代码。
       现在将Discuz!NT的缓存架构说明如下,先请大家看一下Discuz!NT架构图:

         
       其实这个构架说白了就是一个标准的“策略”模式,为了对比方便,我把策略模式的结构图放在下面:


        里面的DNTCache就是“策略”模式的应用场景,而DefaultCache , ForumCache,RssCache等等就是相应的具体策略,每一种策略都会对.NET所提供的缓存机制进行一番“订制”,以实现不同的用途。比如系统DefaultCache在对象到期时提供数据再次加载机制,而ForumCache不使用这种机制,另外还有缓存的到期时间几种策略也各不相同,这都是根据具体的应用场景"量身订制"的。
        说到这里,您所要做的就是下载一份源码按上图索骥就可以把整个缓存机制搞清楚。

        下面对缓存设计所采用的几种技术做一下简要说明。包括XML,XPATH ,"单件模式" 以及跨web园共享数据。
        首先请看一下代码:(xml xpath)

 1 //要存取的xpath格式路径
 2 //要缓存的对象
 3 public virtual void AddObject(string xpath, object o ,string[] files)
 4 {
 5  
 6  //整理XPATH表达式信息
 7  string newXpath = PrepareXpath(xpath);
 8  int separator = newXpath.LastIndexOf("/");
 9  //找到相关的组名
10  string group = newXpath.Substring(0,separator  );
11  //找到相关的对象
12  string element = newXpath.Substring(separator + 1);
13    
14  XmlNode groupNode = objectXmlMap.SelectSingleNode(group);
15  //建立对象的唯一键值, 用以映射XML和缓存对象的键
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   //建立新元素和一个属性 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   //建立新元素和一个属性 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  //向缓存加入新的对象
46  cs.AddObjectWithFileChange(objectId,o,files);
47  
48 }
49 

NET技术Discuz!NT 缓存设计简析 [原创],转载需保留来源!

郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。