54 CHEN

[原创]Discuz! BBS缓存整体方案

[ 文章作者:陈臻 本文版本:v1.0 最后修改:2009.6.22 转载请注明原文链接:http://www.54chen.com/c/611 ]

DZ的缓存方案是经典之作,不论是系统的主动缓存还是帖子内容的被动缓存。在我前面的博文【[原创]Discuz! BBS的主动缓存和被动缓存】里所讲述的是DZ的缓存常用的一种方法,下面再说在DZ系统里如何决定一个内容是不是要缓存。

所有的数据全都缓存,不失为一个好办法。但是,在数据更新要求及时的环境下,例如帖子回复的内容要求立即显示等地,又不得不对其缓存进行更新。所以,基本上每一个成熟的系统,都不会去把所有的东西缓存起来。这时是不是让各位很困惑,缓存就是一把双刃剑,用好了系统效率事半功倍,用得不好,产品功能将受到严重影响。DZ就是一个缓存与不缓存选取得当的系统。

我们一起进入DZ的viewthread.php,也就是负责显示帖子内容的一个文件。代码一开始有这样一个判断:

$page = max($page, 1);

if($cachethreadlife && $forum[‘threadcaches’] && !$discuz_uid && $page == 1 && !$forum[‘special’]) {

viewthread_loadcache();

}

这是什么意思呢?基本上就是在说,当一些系统的设置都满足的时候,只要是第一页就去执行viewthread_loadcache(),各位已经等不及看这个函数的意思了吧,且慢,先说说为什么选中了第一页。在经过大家长期的总结下,发现一个成熟论坛大多数时间会员都会停留在帖子的第一页,所以,DZ大胆地只将第一页进行缓存。

DZ真的是只将第一页进行缓存吗?答案是否定的,下面我们来看viewthread_loadcache()这个函数里的内容。

这个函数写在了viewthread.php的538行,看到这个函数的第一感觉,是专业。DZ的多年开发,已经将论坛的行为研究深深刻在了代码里。如下这段代码,这个函数里的$threadcachemark这个变量,被定义为与帖子的显示顺序、是否加精、此版最后回复天数、帖子浏览数、回复数、每页显示条数进行运算得到的一个值,如果这个值小于了版块的设置,这个帖子的内容才会生效。就也是说,DZ甚至还不是但凡第一页就缓存!

$threadcachemark = 100 - (

$forum[‘displayorder’] * 15 +

$forum[‘digest’] * 10 +

min($forum[‘views’] / max($forum[‘livedays’], 10) * 2, 50) +

max(-10, (15 - $forum[‘lastpostdays’])) +

min($forum[‘replies’] / $_DCACHE[‘settings’][‘postperpage’] * 1.5, 15));

这个经典的公式从何而来?由笔者有幸参加的一次DZ的培训得知,这个公式是多年来长期的积累,不断的尝试,才总结所得。至于更多的细节,大概只有DZ的总设计师才能得知。不过我们也可以从代码里得到一些提示,帖子的属性是可以作为是否缓存的权值的,而这个权值,直接决定了缓存与否。

这样的选取在DZ里到处可见,在存在分页的地方,只需要记住,前两页或者前一页,以及最后两页或最后一页,永远比中间的更值得缓存。如果读者的系统需要一个缓存方案,建议全局统计一下所有的用户关注的点,学习DZ的,将这些关键的点数值化,就一定也能得出一个合适的公式。

一个简约的缓存,每个细节的方案,筑成了DZ整体的坚实。

提示:平时在设计系统的时候,也许并不能考虑到这么细,如果不是受到磁盘空间的限制,您并不需要担心按照什么方案来缓存,用一刀切的方案也不错,也就是把大部分看上去很常用的数据都缓存了,但你需要更多考虑去对比是否需要更新缓存了,比如用最后回复的时间去对比,很多开源系统就都是这样干的。

原创文章如转载,请注明:转载自五四陈科学院[http://www.54chen.com]

Posted by 54chen php, 架构研究

« scp和rsync的限制流量(速度)方法 [原创]使用postgreSQL+bamboo搭建比lucene方便N倍的全文搜索 第一部分 »