假设我们有个文章页要以分页形式显示,分页类型有按分类分页、按热点分页、按最新分页、按自定义方式分页等。这就出现了一个问题:对数据的更新影响到哪些分页是不可知的,不知道需要删除哪些相关的缓存。下文讲介绍一个简单的解决方案来处理这个问题。其实,需要解决的核心问题就一个:增加、删除、修改数据时能够让分页缓存都失效,实现这一点只需要引入版本号就可以了,在所有受影响的memcached的key中都加入版本号,当我们增加、修改、删除文章数据时,版本号+1,这样就等于所有分页相关缓存都失效了。
代码如下:
<?php
//备注:假设下面函数都已初始化$memcached
class Article
{
private $article_version = 'article_version';
public function getArticle($type='new',$page='1',$limit=0){
//设置memcached的key,在key的末端加上版本号
$cache_id = 'art_type'.$type.'_page'.$page.'_limit'.$limit.'v_'.$this->_getArticleVersion();
//得到分页数据
$artdata = $memcached->get($cache_id);
if( FALSE === $artdata) {
//重新从数据库得到数据并设置新的memcached缓存
}
return $artdata;
}
public function updateArticle($conditions,$data){
//更新数据库数据操作
//更新Article的版本,这样所有Article表相关的缓存就都失效了,下次调用getArticle函数的时候将生成新的缓存数据
$this->_setArticleVersion();
}
private function _getArticleVersion(){
$article_version_num = $memcached->get($this->article_version);
if( FALSE === $article_version_num){
$article_version_num = 1;
$memcached->set($this->article_version, $article_version_num, 86400);
}
return $article_version_num;
}
private function _setArticleVersion(){
$article_version_num = $memcached->get($this->article_version);
$article_version_num++;
$memcached->set($this->article_version, $article_version_num, 86400);
}
}
?>
解决方案就比平常的memcached缓存多两个函数:_ getArticleVersion()和_ setArticleVersion(),这样当增加、删除、修改文章时调用_ setArticleVersion()函数,版本号+1,使之前版本的数据都失效,因为在获得文章分页缓存数据时key都加入了_ getArticleVersion()函数,所以得不到新版本号的缓存数据就从数据库查到,再生成新版本的缓存,旧的缓存在时间过期之后会自动释放。