现在的位置: 首页 > 综合 > 正文

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

2013年03月26日 ⁄ 综合 ⁄ 共 2621字 ⁄ 字号 评论关闭

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(); 

 
 

抱歉!评论已关闭.