PHP支持组操作的Memcache类(域操作)

来源:互联网 发布:subversion mac 编辑:程序博客网 时间:2024/06/06 09:07
Memcache是PHP开发中较常用到的缓存方法,在高并发的系统中是必不可少的组成部分。
在实际开发中,Memcache存在一个比较不尽人意的问题,就是Memcache不能支持对key进行的组操作。
 
组操作,也可以称为域操作,比如说某个文章系统,在前台部分使用Memcache缓存了列表页数据、文章详细页数据,两种数据的量都比较多。那么,当后台发布了一篇文章的时候,列表页就应该需要更新到最新的列表——可能涉及到许多个列表页。当然,对文章详细页来说,它是不需要更新的。
 
好的,这个时候我们就需要删除原有缓存,让程序可以自动更新列表页数据。但是使用Memcache的flush函数有个问题,就是它会清空全部的数据,包括列表页和文章页的数据,在大并发的条件下,全部缓存删除后重建缓存的时候,将会有非常高的负载产生。
 
另外,还会有情况就是有些你不愿意删除的缓存变量,也会丢失了,比如说程序的配置,数据库为了提速而存到缓存的表结构等。
 
所以我们需要一个支持组操作的缓存机制,我们就可以把列表页设置成一个组,文章页数据是另外一个组,程序配置又是另外一个组等等。当需要重建列表页的时候,只需要删除列表页这个组里面全部的数据,而不会影响到别的组的数据。
 
测试了几种方案,还是以下的方案最为理想和高速,我们先看代码,再说原理:
 
<?php class MyCache {     private $mmc = null;     private $group = null;     private $version = 1;     function __construct($group){         if(!class_exists('mmcache')){             $this->mmc = false;             return;         }         $this->mmc = new memcache();         $this->mmc->addServer('192.168.1.5', 11211);         $this->mmc->addServer('192.168.1.6', 11211);         $this->group = $group;         $this->version = $this->mmc->get('version_'.$group);     }     function set($key, $var, $expire=3600){         if(!$this->mmc)return;         return $this->mmc->set($this->group.'_'.$this->version.'_'.$key, $var, $expire);     }     function get($key){         if(!$this->mmc)return;         return $this->mmc->get($this->group.'_'.$this->version.'_'.$key);     }     function incr($key, $value=1){         if(!$this->mmc)return;         return $this->mmc->increment($this->group.'_'.$this->version.'_'.$key, $value);     }     function decr($key, $value=1){         if(!$this->mmc)return;         return $this->mmc->decrement($this->group.'_'.$this->version.'_'.$key, $value);     }     function delete($key){         if(!$this->mmc)return;         return $this->mmc->delete($this->group.'_'.$this->version.'_'.$key);     }     function flush(){         if(!$this->mmc)return;         ++$this->version;         $this->mmc->set('version_'.$this->group, $this->version);     } } ?> 


上面的类比较完整,包括链接Memcache服务,设置和获取值,增减值,还有删除key和全删除(flush)。这里包括了常规的Memcache操作功能,和对全删除(flush)操作的扩展。
 
从代码可以看到,支持组的flush功能的实现,是通过version这个key来实现的,也就是每次存该组的变量的时候,变量的key都会加入version值,version值是一个数字(从1开始),当存和取key的时候,version值都会被使用到。
 
当开发者要flush当前组的数据的时候,flush操作只是简单地改变一些version的值(加一),那么,下次存取key的时候,将获取不到原来的值——因为version改变了,也就是取的key名称已经改变了。这样原有的值会被Memcache自动回收,不会出现任何的效率开销。而且程序上只是增加一个version的存和取,数据量极小,对系统效率基本没有任何影响。
 
通过以上的类,可以针对Memcache缓存进行组的操作,而这个PHP类,还可以继续扩展,如加入socket直接访问memcache的接口功能,这样PHP环境中就不需要安装memcache扩展类了,这样更有效避免flush的误操作了,而且在加入apc等缓存机制后,socket访问memcache接口也不会比扩展慢多少。
 
另外,MyCache类还有个附加的功能:当memcache服务失效的时候,MyCache类只是简单返回空值,而不会直接出错。
 
以下附带MyCache类的使用方法:
 
// 引入定义 include('MyCache.php');    // 实例化 $mc = new MyCache('abc'); // 要有域    // 设置值 $mc->set('word', 'hello world', 900);    // 取得值 echo $mc->get('word');    // 删除值 $mc->delete('word'); echo $mc->get('word');    $mc->set('counter', 1, 290000); echo $mc->get('counter');    // 增加值 $mc->incr('counter'); $mc->incr('counter'); echo $mc->get('counter');    // 减少值 $mc->decr('counter'); echo $mc->get('counter');    // 按组删 $mc->flush(); 


 
 
原创粉丝点击