解读Supesite的数据库缓存与文件缓存机制

各种系统开发中都会大量的使用缓存,用于提高程序执行速度,避免过于频繁的查询或者是过于复杂的查询的性能消耗。例如网站名称这样的设置项,每个页 面都会调用到,这属于频繁查询。另外一种比如是一个连接了3,4个表的sql查询,每次查询都会造成很大的数据库消耗,这属于复杂查询。

supesite中的缓存类型

supesite中有2种缓存,一种是文件缓存,一种是数据库缓存。

文件缓存的做法就是执行一次查询,然后将返回的结果生成一个.php的缓存文件,可以直接在程序中include进来,所有需要的地方都是直接include,这样就减少了数据库的查询。(当然,这里眼尖的同学会说这个增加了磁盘IO,等会下说个权衡问题)

数据库缓存的做法是将查询结果,再序列化成字符串,保存到数据库,碰到相同条件的查询语句时候,直接将查询结果又从数据库中读取出来。这里有些同学 不理解,既然是减少数据库查询的负担,为什么又把结果保存到数据库再读出来? 这是我们刚刚提到的复杂查询的缓存。我们将复杂的,性能消耗很高的查询结果保存到数据库,下次碰到一样的查询语句的时候,直接取出来,消耗仅仅是一个最简 单的select语句而已,可以完全避免复杂sql的性能消耗。

以上是2种缓存文件实现提高性能的方式。具体缓存机制如何实现呢?

缓存机制的实现

无论文件缓存还是数据库缓存,实现都包括3个方面:

生成,更新,调用。

文件缓存的生成

文件缓存较为简单。生成文件缓存,只要将数据库结果整理成字符串,然后应用php自带的fwrite()函数将字符串写入文件即可。当然也要注意生成的文件语法要正确,才可以保证include的时候不会出错。

supesite中生成缓存的代码:

其中$tarr是结果集数据组,指定文件名,生成文件就行.arrayeval是supesite中转换数据为缓存内容的函数,具体如下:

writefile是supesite封装的一个写文件的函数。主要是保证生成的php文件不会存在语法出错的状况,并且增加一定的可读性。

文件缓存的更新

文件缓存的更新,就涉及到了整个业务机制了。有两种更新需求,一种是即时更新,就是一旦结果集发生变化,缓存文件也要更新,适应于对实时性要求比较 高的配置项。另一种是定时更新,每隔一段时间就检查是否到了更新的时间点,到了时间点之后,无论结果是否有变化,都执行更新。不过两种方式没有绝对的性能 优劣。假设结果集更新非常频繁,那么显然定时更新的方式性能较优,但是如果结果集很久才变化一次,那么即时更新的方式更划算。

即时更新的实现难度不大,只要在更新结果集的时候同时更新缓存即可。比如系统修改了设置项,那么在执行完数据库修改语句后,再加上缓存文件的更新代码即可。

定时更新则会稍微有一点点麻烦,你需要一个配置项来记住当前文件更新的时间间隔(例如1小时),然后每次触发执行的时候,都判断下当前时间与文件时间的差异是否达到了更新的间隔。

文件缓存的调用

文件缓存的调用非常简单,php中只要include指定的文件就可以了。当然,要稍微注意下include,require,include_once,require_once的差异。一般可使用include_once。

数据库缓存的实现

数据库缓存的整体实现机制相比文件缓存来说复杂得多,需要一整套完整的从生成更新到调用的机制。

supesite中采用的机制叫block,中文应该叫簇。这是一个相当好的设计,它极大的简化了数据调用的方式,并且与数据库缓存机制紧密结合,目前这种机制在各种开源CMS中都很流行。

首先来看看整套缓存表的设计,整个建表语句如下:

show create table supe_cache;

cachekey缓存主键,用于识别缓存,uid基本是无用,可以忽略。cachename是supesite中区分缓存的内容的类型的,例如分类 调用缓存,新闻调用缓存,评论调用缓存等,通过cachename字段,可以允许后台单独对某些分类的缓存进行更新。value则是整个调用结果集,它是 php中的结果数组的序列化字符串。updatetime记录的是下次缓存要更新的时间。

通过这个设计,可以得出整个数据库缓存的实现思路:生成缓存的时候,生成一个唯一的cachekey作为主键,将结果集序列化为数组保存在数据库 中,并记录下次更新的时间。调用缓存的时候凭借cachekey主键获取,并判断updatetime时间是否已经到达更新的时间点,如果需要更新,则更 新缓存表。否则直接读取缓存的结果集。

这里面围绕着一个核心的技术问题:

如何将sql调用跟唯一的cachekey对应起来?也就是说我执行一条sql语句来查询数据,这个查询怎么生成一个唯一的cachekey,然后我下次再次执行同样的sql就可以跟通过cachekey找到缓存结果?

这里就是supesite的核心函数block的功劳了。

 

 

 

FROM:http://www.fangyuqiang.com/archives/1025

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章