This is my 1st version, maybe i can use getMulti and setMulti refactor it(优化之).
class CacheUtils {
const CACHE_MAX_VERSION = 10;
private $memcache;
private static $instance;
private function __construct() {
$this->memcache = new Memcache();
$this->memcache->connect('127.0.0.1', 11211) or die('Can not connect to memcached server.');
}
public static function getInstance() {
if(self::$instance == null) {
self::$instance = new CacheUtils();
}
return self::$instance;
}
public function addElementVersion($type) {
$key = 'Element_Version:'.$type;
$ver = $this->memcache->increment($key);
if ($ver == false) {
$ver = $this->memcache->set($key, 0);
$ver = $this->memcache->increment($key);
}
else if ($ver > self::CACHE_MAX_VERSION) {
// flush all! keep data correct
$this->memcache->flush();
}
return $ver;
}
public function getElementVersion($type) {
$key = 'Element_Version:'.$type;
return $this->memcache->get($key);
}
public function addElement($elem) {
$key = 'Element:'.$elem->type.':'.$elem->id;
$retE = $this->memcache->set($key, $elem);
$retV = $this->addElementVersion($elem->type);
return $retE && $retV;
}
public function getElement($type, $id) {
$key = 'Element:'.$type.':'.$id;
return $this->memcache->get($key);
}
public function getElementListVersion($type, $sql) {
$key = 'Element_List_Version:'.$type.':'.$sql;
return $this->memcache->get($key);
}
public function addElementList($type, $list, $sql = '') {
$keyList = 'Element_List:'.$type.':'.$sql;
$keyVersion = 'Element_List_Version:'.$type.':'.$sql;
$ver = $this->getElementVersion($type);
$retL = $this->memcache->set($keyList, $list);
$retV = $this->memcache->set($keyVersion, $ver);
return $retL && $retV;
}
public function getElementList($type, $sql = '') {
$keyList = 'Element_List:'.$type.':'.$sql;
$elementVersion = $this->getElementVersion($type);
$elementListVersion = $this->getElementListVersion($type, $sql);
if ($elementListVersion != $elementVersion)
return false;
else
return $this->memcache->get($keyList);
}
}
Test Case:
<?php
require_once 'PHPUnit/Framework.php';
require_once dirname(__FILE__).'/../CacheUtils.php';
class Person {
public $id;
public $name;
public $age;
public $createTime;
public $type;
function __construct($id, $name, $age) {
$this->id = $id;
$this->name = $name;
$this->age = $age;
$this->type = get_class($this);
$this->createTime = time();
}
}
/**
* Test class for CacheFacade.
* Generated by PHPUnit on 2010-03-28 at 04:07:43.
*/
class CacheUtilsTest extends PHPUnit_Framework_TestCase {
/**
* testAddElement
*/
public function testAddAndGetElement() {
$cacheUtils = CacheUtils::getInstance();
$person = new Person(101,'Linx', 29);
$this->assertEquals(true, $cacheUtils->addElement($person));
$personGet = $cacheUtils->getElement('Person', 101);
$this->assertEquals('Linx', $personGet->name);
var_dump($personGet);
}
public function testAddAndGetElementList() {
$cacheUtils = CacheUtils::getInstance();
$person1 = new Person(101,'Linx1', 29);
$person2 = new Person(102,'Linx2', 30);
$list = array($person1, $person2);
$this->assertEquals(true, $cacheUtils->addElementList('Person', $list));
$listGet = $cacheUtils->getElementList('Person');
$this->assertEquals(2, count($listGet));
$this->assertEquals('Linx1', $listGet[0]->name);
var_dump($listGet);
}
public function testAddAndGetElementListExpired() {
$cacheUtils = CacheUtils::getInstance();
$person1 = new Person(101,'Linx1', 29);
$person2 = new Person(102,'Linx2', 30);
$list = array($person1, $person2);
$this->assertEquals(true, $cacheUtils->addElementList('Person', $list));
// Person v2
$this->assertEquals(true, $cacheUtils->addElement($person1));
// v1 is expired
$listGet = $cacheUtils->getElementList('Person');
$this->assertEquals(false, $listGet);
var_dump($listGet);
}
}
?>
posted @ 2010-03-29 01:09 果果’er 阅读(260) 评论(5)
编辑
终于还是遇到这个问题了,之前听 @huacnlee 说过,当时不知道具体场景也没有仔细考虑过。
这两天想了一下,看了些文章介绍,准备自己实现一个以版本号来处理的批量删除(过期)问题。
参考:
memcached应用策略
http://blog.sina.com.cn/s/blog_5378b2830100figs.html
memcached批量删除方案探讨
http://it.dianping.com/memcached_item_batch_del.htm
memcached缓存批量更新解决方案探讨
http://bbs.phphubei.com/thread-10038-1-1.html
另外好像看过一篇跟版本号方式处理的关的文章没找到了。
posted @ 2010-03-29 00:43 果果’er 阅读(503) 评论(4)
编辑
一开始就在疑惑为什么会有两个库,且在php.net官方都有文档支持。
之前尝试用的是memcache,后来发现memcached支持setMulti方法,准备转向使用memcached库了。
(试了下,实际上,memcache从支持多值set,但文档上还没有,看changelog好像是3.0开始支持,稳定版可能不带此功能。)
至于效率,也不清楚会有多大差距。
这里有一篇文章也说到,memcached是基于libmemcached,可能要好一些。
参考: http://www.surfchen.org/archives/371
Memcached manual:
http://cn.php.net/manual/en/book.memcached.php
Memcache manual:
http://cn.php.net/manual/en/book.memcache.php
Memcached 协议中英文对照:
http://blog.s135.com/book/memcached/
posted @ 2010-03-29 00:35 果果’er 阅读(317) 评论(0)
编辑