google的leveldb越来越被很多人接受。国内的ideawu基于leveldb还写了一个ssdb的前置扩展用来实现了很多功能,比如标准的getset和hget,hset还有zset,zget,也实现了队列。当然pub/sub就没有办法实现了。毕竟它和redis还是有点区别。
基于标准的ssdb的类,写了个小扩展,扩展了Yii的Cache类:
PHP代码
- 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。结果浪费了很长时间