关于.Net开发下的散布式缓存设计
核心提示:本文主要论证与数据缓存相干的1些利用与题目。在。Net 平台下面我把缓存从功用大致分为两类,数据对象缓存和页面输出缓存。 对数据缓存来讲是由System.Web.Caching.Cache这个类来实现
本文主要论证与数据缓存相干的1些利用与题目。在。Net 平台下面我把缓存从功用大致分为两类,数据对象缓存和页面输出缓存。 对数据缓存来讲是由System.Web.Caching.Cache这个类来实现
最近拜读了关于。Net开发下的Discuz!NT的缓存设计的1篇文章Discuz!NT 缓存设计简析 [原创],很有些想法,姑且写在这里让大家拍砖吧。
缓存真是个好东西,在大型的系统中可以有效地提升系统的速度,此乃空话就未几说了,在。Net 平台下面我把缓存从功用大致分为两类,数据对象缓存和页面输出缓存。 对数据缓存来讲是由System.Web.Caching.Cache这个类来实现,可以从上下文对象Context.Cache 来获得这个对象的援用。而页面/控件输出缓存则是由。Net环境在运行时根据头部的缓存申明来控制缓存策略。 本文主要论证与数据缓存相干的1些利用与题目。
文中提到了"没法跨Web园共享数据的题目",固然提到解决方案就是使用XML文件来寄存缓存的键值,这里有1个迷惑,就是。Net的Web园既然是进程独立的又何来共享之说呢,真要是这样的话即使是通过XML文档写进缓存键值缓存的对象也不能同时在两个进程中共享,而这里取得的好处仅是避免了在其它的进程中读到了已在当前进程中失效的“脏”缓存数据,这样的话开几个Web园就会产生几个缓存的对象对系统资源的利用系就比较低了。 假设是用Web场布署的话浪费就更多了,或许是还少有论坛到达这样的范围故不在设计能力的范围中吧。CommunityServer也是使用了这个系统对象,并对它作了1些包装构成了CommunityServer.Components.CSCache这个类,还是不错的,可以在项目当选择使用。
基于这个类的应注实现还有EnterpriseLibrary的CacheBlock里面的NullBackingStore方式,但是为了满足多进程/服务器共程缓存数据的需求EntLib还提供了将SQL SERVER作为后端存储设备的方案,这样在性能要求不是太严,客户端连接不是太多的情况下也能够使用这类方式。只需要将EntLib 配置为共享数据库分区的工作方式即可,所有的CacheManager实例都有对缓存块的读写权,固然你也可配置为只答应1个实例写,其它的来读。
那末还有无更好的办法呢,实在是有的。 不过我很希奇在。Net平台下居然没有“原生态”的散布式缓存解决方案,或许是俺孤陋寡闻吧,有哪位达人知道的请分享。还好我们有Memcached这东西,它在PHP平台上已取得了巨大的成功,是优秀的散布式缓存解决方案,可以参看这篇文章 , 大型的站点上应当必不可少吧。有举的同学可以往看看, 另外还想好1个思路, 就是在EntLib的基础上作扩大实现IBackingStore 接口从BaseBackingStore派生1个实现出来,再经过Remoting或ICE这样的散布式中间件技术应当也能够实现的类似的功能吧。
用XML作为缓存键的存储方式倒是1个不错的想法,这样在批量移除缓存项的时候就不需要作扫描而直接得到相应的缓存键值,跟散布式缓存作1个整合应当是1个不错的方案。
好了,让我们再回头看看Discuz!NT在页面缓存上有些甚么高招。
总的说来我是不怎样喜欢。Net2.0提供的页面输出缓存功能,主要是不能手动地控制页面缓存的过期,而使有缓存依托项仿佛也有点不爽。事实上使用数据绑定控件相对来讲是比较消耗资源的,一样的数据我用StringBuilder直接拼出来输出速度要快很多,测试代码比较简单我这里就不给了,大家可以自己往测往,Discuz!NT在设计中也大量地采取了这样的方法(怪不得速度这么快呢;))。1般来讲模版被保存后后台会在aspx目录天生对应的页面文件, 比如你有1个页面,上面需要显示1个来访者的姓名,它的伪代码看起来多是这个模样
模版文件内容show.html:
以下为援用的内容:
Hello, Your name is <% yourname %> 天生的文件 show.aspx templateBuilder.AppendLine(""); templateBuilder.AppendLine(""); templateBuilder.AppendLine("Hello, Your name is " + this.yourname); templateBuilder.AppendLine(""); templateBuilder.AppendLine("");
templateBuilder.AppendLine(""); templateBuilder.AppendLine(""); templateBuilder.AppendLine("Hello, Your name is " + this.yourname); templateBuilder.AppendLine(""); templateBuilder.AppendLine(""); |
这里的this.yourname对应着相应页面后台类里面的1个属性,由程序在运行时进行初始化赋值,这样最后得到的页面履行结果便可以够从这个templateBuilder对象的ToString()方法得到, templateBuilder也就是1个页面后台类里面的StringBuilder类的实例,最后在页面履行终了后的OnLoad事件中根据不同的页面类型,如首页,频道首页,内容页等, 使用不同的缓存策略将页面履行结果的HTML代码插进到缓存中,下1个要求进来的时候在进进页面生命周期之前的HttpModule(这里面还包括地址重写功能代码)中判定这个缓存是否是有效,直接从内存读取缓存发回客户端。这样速度固然就快了, 页面上看到的履行时间自然是0ms. 不过对登陆用户来讲由于要显示不同的登陆信息所以不能使用匿名的缓存文件版本,所以说1旦你登陆页面才会真正履行1次,但是上面要显示的数据都有独立的缓存项,所以仅仅是重新组装1次页面代码罢了,速度还是比较快的,在官方论坛上看到首页加载时间是15ms, 够快的了。 愚以为连这个时间实在也是可以再节省节省的。 比如用户登陆信息这部份东西可以天生1段JS, 在向浏览器发出了匿名用户的缓存版本时再判定假设用户登陆了就追加这样1段JS代码,在里面往把相应的HTML替换掉便可以够了,也能够使用AJAX技术在客户端往取,这样就解决了已登陆用户和未登陆用户在共享缓存版本上的题目,最少在首页这1级是可以的吧,其它的主要页面不好说应当也差未几,俺对论坛程序的流程不是很了解。
从另1个角度讲已登陆用户不应当速度比匿名用户还慢吧~~~;)
HOHO,终究完成了,先写这些吧。聊点别的`~~整体上看俺觉得实用的就是最好的,不要说DNT的设计有多烂多烂,层次结构多不公道,代码多不OO,但是在这样1个特定的利用环境下它提供了1种相对灵活和高速的解决的方案,我觉得就是1个正确的选择。量文体衣做出来的东西固然可保护可重用性较差还是有它的好处的,俺自己也比较偏向于这类针对性很强的解决方案思路,希看DNT能做得更好~~~正如BlogEngine这样的程序,它几近将很多的数据都Load到内存里面,数据存储默许的也是XML的存储方式,你很难往讲它是1个糟的程序,由于它有特定的利用处景,合适的才是最好的~~~~
本文基于DNT 2.0 RC1, 不当的地方请大家斧正, 谢谢。
唐山网站建设www.fw8.netTAG:数据,代码,对象,页面,缓存
评论加载中...
|