google的leveldb越来越被很多人接受。国内的ideawu基于leveldb还写了一个ssdb的前置扩展用来实现了很多功能,比如标准的getset和hget,hset还有zset,zget,也实现了队列。当然pub/sub就没有办法实现了。毕竟它和redis还是有点区别。
基于标准的ssdb的类,写了个小扩展,扩展了Yii的Cache类:
class CSsdbCache extends CCache
{
/**
* @var string hostname to use for connecting to the redis server. Defaults to '127.0.0.1'.
*/
public $hostname = '127.0.0.1';
/**
* @var int the port to use for connecting to the ssdb server. Default port is 8888.
*/
public $port = 8888;
/**
* @var float
*/
public $timeout = 2000;
public $serializer = false;
public $_cache;
protected $_cachekeys = 'ssdb_cachekey';
public function init() {
parent::init();
}
/**
* @return SSDB
*/
public function getSsdbCache() {
if ($this->_cache !== null)
return $this->_cache;
else {
return $this->_cache = new SimpleSSDB($this->hostname, $this->port, $this->timeout);
}
}
public function getkeys() {
return $this->getSsdbCache()->hkeys($this->_cachekeys, "", "", $this->getSsdbCache()->hsize($this->_cachekeys));
}
/**
* Retrieves a value from cache with a specified key.
* This is the implementation of the method declared in the parent class.
* @param string $key a unique key identifying the cached value
* @return string|boolean the value stored in cache, false if the value is not in the cache or expired.
*/
protected function getValue($key) {
return unserialize($this->getSsdbCache()->get($key));
}
/**
* Stores a value identified by a key in cache.
* This is the implementation of the method declared in the parent class.
* @param string $key the key identifying the value to be cached
* @param string $value the value to be cached
* @param integer $expire the number of seconds in which the cached value will expire. 0 means never expire.
* @return boolean true if the value is successfully stored into cache, false otherwise
*/
protected function setValue($key, $value, $expire) {
$this->getSsdbCache()->hset($this->_cachekeys, $key, 1);
if ($expire > 0) {
//$expire += time();
return $this->getSsdbCache()->setx($key, serialize($value), (int) $expire);
}
else {
return $this->getSsdbCache()->set($key, serialize($value));
}
}
/**
* Stores a value identified by a key into cache if the cache does not contain this key.
* This is the implementation of the method declared in the parent class.
* @param string $key the key identifying the value to be cached
* @param string $value the value to be cached
* @param integer $expire the number of seconds in which the cached value will expire. 0 means never expire.
* @return boolean true if the value is successfully stored into cache, false otherwise
*/
protected function addValue($key, $value, $expire) {
return $this->setValue($key, $value, $expire);
}
/**
* Deletes a value with the specified key from cache
* This is the implementation of the method declared in the parent class.
* @param string $key the key of the value to be deleted
* @return boolean if no error happens during deletion
*/
protected function deleteValue($key) {
$this->getSsdbCache()->hdel($this->_cachekeys, $key);
return $this->getSsdbCache()->del($key);
}
/**
* @return boolean whether the flush operation was successful.
*/
protected function flushValues() {
$this->getSsdbCache()->multi_del($this->getkeys());
return $this->getSsdbCache()->hclear($this->_cachekeys);
}
}
其实代码很简单,不过由于ssdb默认没有serialize功能,所以在存储之前,得先主动的serialize,然后get的时候unserialize。不然就没有办法存储数组了。
由于ssdb没有flush功能。所以利用hget/hset将所有的key存储下来。flush的时候把hget获取的key读出来删除。然后再清掉这个hget的key
最后还有expire。ssdb里的setx第三个参数。。。居然不是expire,而是ttl。开始的时候,一直都当成expire。结果浪费了很长时间

评论 (1)