您现在的位置是:首页 > cms教程 > discuz教程discuz教程
Discuz实现NT缓存设计
从寒2025-06-23 23:26:58discuz教程已有2人查阅
导读作为一个社区类型软件,大并发支持和高效稳定运行永远是“硬道理”,而有效安全的使用缓存恰恰能起到事倍功半的效果。而.NET本身所提供的缓存机制又显得过于“单薄”,比如说订制
作为一个社区类型软件,大并发支持和高效稳定运行永远是“硬道理”,而有效安全的使用缓存恰恰能起到事倍功半的效果。而.NET本身所提供的缓存机制又显得过于“单薄”,比如说订制不太灵活方便, 缓存对象之间层次感不强, 使用时缺乏统一的管理等等。
DiscuzNT缓存产生背景:
在去年五月份我加入DiscuzNT项目组时,发现这个项目当时还未使用缓存机制。主要原因是项目还处于起步阶段,很多东西还只是有想法,但未付诸实施,或还没找到合适的方案, 而缓存就是其中一个到底该不该使用,如果使用的该到底能多大程度缓解数据库压力以及开发成本的东西。
我当时正好有一个比较好的“原型”(从一本书上看到的源码),也就是今天DiscuzNT所使用的缓存机制的雏形,但当时它在功能上还很不健全且存在一些“致命的” BUG, 但实现简单的缓存数据对象还是绰绰有余的,于是我通过一个简单的测试用例(缓存数据表和StringBuilder对象)和雪人一起讨论并分析后得到一些数据,基本上肯定了使用缓存解决对数据库象中经常访问但又不经常更新的数据进行缓存的使用方案,同时也要求这个缓存机制要使用起来尽可能的简单,同时功能扩展要非常方便。
因此本人就在这个“原型”的基本上进行了一段时间的功能扩展和BUG修正才得到今天大家所看到的这部分代码。
现在将DiscuzNT的缓存架构说明如下,其实这个构架说白了就是一个标准的“策略”模式,为了对比方便,看到了吧,里面的DNTCache就是“策略”模式的应用场景,而DefaultCache , ForumCache,RssCache等等就是相应的具体策略,每一种策略都会对.net所提供的缓存机制进行一番“订制”,以实现不同的用途。比如系统DefaultCache在对象到期时提供数据再次加载机制,而ForumCache而不使用这种机制,另外还有缓存的到期时间几种策略也各不相同,这都是根据具体的应用场景"量身订制"的。
说到这里,您所要做的就是下载一份源码按上图索骥就可以把整个缓存机制搞清楚。下面对缓存设计所采用的几种技术做一下简要说明。包括XML,XPATH ,"单件模式" 以及跨web园共享数据。
首先请看一下代码:(xml xpath) 为什么要用XML, 主要是为了使用XML中的层次化功能以及相关的结点添加,替换,移除,还有就是当希望对缓存的结构信息进行“持久化”操作时会很方便等。XPATH 便于能过层次表达式(hierarchical expression) 对XML文件进行查找搜索。
通过上面或其它的类似代码,就可以构建起一个xml树来管理已加入到系统的缓存对象了。使用"单件模式"模式生成全局唯一的“应用场景”,因为缓存这种东西通常在存储共享数据时它的效果较好,编码也最容易实现和管理,同时项目本身基本上就是对经常访问但不经常改变的数据库数据(可看成是共享数据)进行缓存,所以使用单件模式就顺理成章了。
请看如下代码: 小插曲:
1.项目到了beta版时出现了无法跨web园共享数据的问题。它的表现是这样的,当你在IIS服务的应用程序池中设置2个或以上的WEB园时,这时你在后台更新缓存时,就是出现缓存“隔三差五”数据不更新或轮换更新的情况。说白了,就是只有一个应用进程中的数据缓存被更新,而其余的进程中所有数据还没事人似的保留原有的面貌。这个问题主要是因为static的数据实例(也就是上面所有的单体代码中的对象)虽然而当前进程中“唯一”,但在其它进程中却各自都有一个造成的。一开始我也很惊讶,为什么微软不能像提供“全局”钩子那样的技术一样提供一种跨WEB园来共享数据的技术或关键字呢,不过一转念也猜出了一二分,必定多WEB园是一种让程序(WEB)跑起来更加安全,稳定快速的“解决方案”。 因为谁都不好说自己的程序一点BUG没有,即有真有这样的代码,但当遇上运行环境这个因素后,也会表现得有些难以控制。
但微软通过web园这个技术就会把运行在几个不同进程下的程序相互隔离,使其谁也不影响到谁,即使其中一个进程down了,而其它进程依就会继续正常 "工作" 。因此程序中的对象实例和所有资源每个进程中都会保存一份,完全相同。而如果引用共享机制就有可能出现当进程共享的数据或程序对象出现问题时,所有进程就可能都玩完了, 因此就需要进程隔离。
说是这么说,但总也要想个办法解决当时面临的问题吧。之前开会其中的一段话我至今还记忆犹新,他说CPU访问内存的速度和访问硬盘的速度在某些情况下是相近的,如果我没理解的话比如说“虚拟缓存”或较新频繁访问的硬盘区段,这些地方的代码或文件会有比较高的运行和访问效率。因此,我想到了使用文件标志关联的方法来解决这个多进程问题。接着就顺理成章的使用了文件修改日期这个属性进行在多进程下缓存是否更新的依据了,大家可以到开源下载包中的config文件夹下把一个cache.config的文件,对应较新的数据项再回过头来看如下代码就会一清二楚了: 2.另外需要说明的是在4月份时缓存机制出现了一些问题,比如缓存数据丢失以及在.net2下的死循环的问题,后来在雪人的建议下采用每个缓存都有缓存标志来解决数据丢失的问题。也就是如下的代码段: 而死循环的问题主要是因为.net2下的缓存回调加载机制和程序本身的一个BUG造成的,目前已修正, 大家请放心使用。目前已开发但还未使用的功能:
1.一键多值:请看DNTCache代码段中的AddMultiObjects(string xpath,object[] objValue),获取时使用object[] RetrieveObjectList(string xpath)方法返回即可,这样就可以用一个xpath来存取一组对象了。它的实现代码也相对简单,这里就不多说了,只把代码贴在此处。 2.批量移除缓存
它主要是利用XML有按路径层次存储的特点才这样做的,主要是去掉位于当前路径下的所有子结点的缓存数据。
它的函数声明如下:RemoveObject(string xpath, bool writeconfig)它的实现代码也相对简单,这里就不多说了, 只把代码贴在此处。 已开发出来,但却去掉了的功能。在正式版出现之前,后台管理中有记录缓存日志的功能,它的实现方式是基于"访问者"模式实现的(大家应该可以在项目中找到这个类LogVisitor)。但因为后来不少站长反映日志表操作的过于频繁导致日志记录急剧增加,而把这部分功能拿下了。我在这里说出来就是想给大家提个醒,对于新功能或新技术的追求要非常谨慎,要不就会出现您费尽千辛万苦开发的功能,之后却没人买帐就郁闷了。
之后需要说明的就是,为什么要先把这块功能先发到园子里来。因为我们产品的DiscuzNT2.0产品即将发布,而整个产品的架构也出现了不少变化,而由于缓存结构相对稳定,所以变化的不大。这才在今天发个BLOG讲给大家的。
DiscuzNT缓存产生背景:
在去年五月份我加入DiscuzNT项目组时,发现这个项目当时还未使用缓存机制。主要原因是项目还处于起步阶段,很多东西还只是有想法,但未付诸实施,或还没找到合适的方案, 而缓存就是其中一个到底该不该使用,如果使用的该到底能多大程度缓解数据库压力以及开发成本的东西。
我当时正好有一个比较好的“原型”(从一本书上看到的源码),也就是今天DiscuzNT所使用的缓存机制的雏形,但当时它在功能上还很不健全且存在一些“致命的” BUG, 但实现简单的缓存数据对象还是绰绰有余的,于是我通过一个简单的测试用例(缓存数据表和StringBuilder对象)和雪人一起讨论并分析后得到一些数据,基本上肯定了使用缓存解决对数据库象中经常访问但又不经常更新的数据进行缓存的使用方案,同时也要求这个缓存机制要使用起来尽可能的简单,同时功能扩展要非常方便。
因此本人就在这个“原型”的基本上进行了一段时间的功能扩展和BUG修正才得到今天大家所看到的这部分代码。
现在将DiscuzNT的缓存架构说明如下,其实这个构架说白了就是一个标准的“策略”模式,为了对比方便,看到了吧,里面的DNTCache就是“策略”模式的应用场景,而DefaultCache , ForumCache,RssCache等等就是相应的具体策略,每一种策略都会对.net所提供的缓存机制进行一番“订制”,以实现不同的用途。比如系统DefaultCache在对象到期时提供数据再次加载机制,而ForumCache而不使用这种机制,另外还有缓存的到期时间几种策略也各不相同,这都是根据具体的应用场景"量身订制"的。
说到这里,您所要做的就是下载一份源码按上图索骥就可以把整个缓存机制搞清楚。下面对缓存设计所采用的几种技术做一下简要说明。包括XML,XPATH ,"单件模式" 以及跨web园共享数据。
首先请看一下代码:(xml xpath) 为什么要用XML, 主要是为了使用XML中的层次化功能以及相关的结点添加,替换,移除,还有就是当希望对缓存的结构信息进行“持久化”操作时会很方便等。XPATH 便于能过层次表达式(hierarchical expression) 对XML文件进行查找搜索。
通过上面或其它的类似代码,就可以构建起一个xml树来管理已加入到系统的缓存对象了。使用"单件模式"模式生成全局唯一的“应用场景”,因为缓存这种东西通常在存储共享数据时它的效果较好,编码也最容易实现和管理,同时项目本身基本上就是对经常访问但不经常改变的数据库数据(可看成是共享数据)进行缓存,所以使用单件模式就顺理成章了。
请看如下代码: 小插曲:
1.项目到了beta版时出现了无法跨web园共享数据的问题。它的表现是这样的,当你在IIS服务的应用程序池中设置2个或以上的WEB园时,这时你在后台更新缓存时,就是出现缓存“隔三差五”数据不更新或轮换更新的情况。说白了,就是只有一个应用进程中的数据缓存被更新,而其余的进程中所有数据还没事人似的保留原有的面貌。这个问题主要是因为static的数据实例(也就是上面所有的单体代码中的对象)虽然而当前进程中“唯一”,但在其它进程中却各自都有一个造成的。一开始我也很惊讶,为什么微软不能像提供“全局”钩子那样的技术一样提供一种跨WEB园来共享数据的技术或关键字呢,不过一转念也猜出了一二分,必定多WEB园是一种让程序(WEB)跑起来更加安全,稳定快速的“解决方案”。 因为谁都不好说自己的程序一点BUG没有,即有真有这样的代码,但当遇上运行环境这个因素后,也会表现得有些难以控制。
但微软通过web园这个技术就会把运行在几个不同进程下的程序相互隔离,使其谁也不影响到谁,即使其中一个进程down了,而其它进程依就会继续正常 "工作" 。因此程序中的对象实例和所有资源每个进程中都会保存一份,完全相同。而如果引用共享机制就有可能出现当进程共享的数据或程序对象出现问题时,所有进程就可能都玩完了, 因此就需要进程隔离。
说是这么说,但总也要想个办法解决当时面临的问题吧。之前开会其中的一段话我至今还记忆犹新,他说CPU访问内存的速度和访问硬盘的速度在某些情况下是相近的,如果我没理解的话比如说“虚拟缓存”或较新频繁访问的硬盘区段,这些地方的代码或文件会有比较高的运行和访问效率。因此,我想到了使用文件标志关联的方法来解决这个多进程问题。接着就顺理成章的使用了文件修改日期这个属性进行在多进程下缓存是否更新的依据了,大家可以到开源下载包中的config文件夹下把一个cache.config的文件,对应较新的数据项再回过头来看如下代码就会一清二楚了: 2.另外需要说明的是在4月份时缓存机制出现了一些问题,比如缓存数据丢失以及在.net2下的死循环的问题,后来在雪人的建议下采用每个缓存都有缓存标志来解决数据丢失的问题。也就是如下的代码段: 而死循环的问题主要是因为.net2下的缓存回调加载机制和程序本身的一个BUG造成的,目前已修正, 大家请放心使用。目前已开发但还未使用的功能:
1.一键多值:请看DNTCache代码段中的AddMultiObjects(string xpath,object[] objValue),获取时使用object[] RetrieveObjectList(string xpath)方法返回即可,这样就可以用一个xpath来存取一组对象了。它的实现代码也相对简单,这里就不多说了,只把代码贴在此处。 2.批量移除缓存
它主要是利用XML有按路径层次存储的特点才这样做的,主要是去掉位于当前路径下的所有子结点的缓存数据。
它的函数声明如下:RemoveObject(string xpath, bool writeconfig)它的实现代码也相对简单,这里就不多说了, 只把代码贴在此处。 已开发出来,但却去掉了的功能。在正式版出现之前,后台管理中有记录缓存日志的功能,它的实现方式是基于"访问者"模式实现的(大家应该可以在项目中找到这个类LogVisitor)。但因为后来不少站长反映日志表操作的过于频繁导致日志记录急剧增加,而把这部分功能拿下了。我在这里说出来就是想给大家提个醒,对于新功能或新技术的追求要非常谨慎,要不就会出现您费尽千辛万苦开发的功能,之后却没人买帐就郁闷了。
之后需要说明的就是,为什么要先把这块功能先发到园子里来。因为我们产品的DiscuzNT2.0产品即将发布,而整个产品的架构也出现了不少变化,而由于缓存结构相对稳定,所以变化的不大。这才在今天发个BLOG讲给大家的。
本文标签:
很赞哦! (1)
暂无内容 |
暂无内容 |
相关文章
暂无内容 |
暂无内容 |
随机图文
Discuz解决安装时报错run_sql_error的方法
本文实现功能解决在MySQL8.0安装discuz报错run_sql_error如果想直接看解决结果,直接去看解决问题目录discuz实现自动注册登录的方法
1.从原有系统进入论坛自动登录和注册2.实现弹框在本页面,不进行跳转3.js在页面加载时直接发起注册请求这个功能之前使用的uc_user_register这个函数来处理的,但是今天在开发用户空间时就会出现问题。Python实现Discuz附件下载权限绕过漏洞
最近压力有些大,想玩点游戏放松下,去Mac论坛下载,发现需要各种权限,于是蛋疼了。上网查了discuz! x3.1破解,手动替换,发现出现“链接已过期”。Discuz实现NT缓存设计
作为一个社区类型软件,大并发支持和高效稳定运行永远是“硬道理”,而有效安全的使用缓存恰恰能起到事倍功半的效果。而.NET本身所提供的缓存机制又显得过于“单薄”,比如说订制
留言与评论 (共有 0 条评论) |