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