使用memcache和redis实现队列

队列的基本功能是:压入和弹出,先进先出。

memcache的实现方式

使用memcache实现队列,需要使用两个key来标记队列的状态:pushKey 记录压入队列的总数,popKey记录弹出队列的总数。

压入数据:pushKey初始值为0,每压入队列一个数据的时候,pushKey自增1。

弹出数据:popKey初始值为0,每从队列中弹出一个数据的时候,popKey自增1。同时删除队列弹出数据的时候,从小标0开始,实现了先进先出的特点。弹出数据的实质是:获取这个数据,然后在把这个数据从队列中删除

使用memcache和redis实现队列

队列初始化代码

[php] view plain copy
  1. public function __construct($queuearray $config)  
  2. {  
  3.     if (! $queue) {  
  4.         throw new Core_Exception_Fatal('队列名不能为空');  
  5.     }  
  6.   
  7.   
  8.     // 连接实例  
  9.     $this->_memcache = new Com_Cache_Memcache();  
  10.   
  11.     // 初始化键名  
  12.     $this->_pushedCountKey = 'Queue:' . strtoupper($queue) . ':PushedCount'// 已压进元素数  
  13.     $this->_popedCountKey  = 'Queue:' . strtoupper($queue) . ':PopedCount';  // 已弹出元素数  
  14.     $this->_queueDataKey   = 'Queue:' . strtoupper($queue) . ':Data';        // 队列数据前缀  
  15. }  

PUSH数据

[php] view plain copy
  1. public function push($value)  
  2. {  
  3.     if (! $value) {  
  4.         return false;  
  5.     }  
  6.   
  7.     $pushed = intval($this->_memcache->get($this->_pushedCountKey));  
  8.   
  9.     // 压进  
  10.     $key = $this->_queueDataKey . ':' . $pushed;  
  11.     if (! $this->_memcache->set($key$value)) {  
  12.         return false;  
  13.     }  
  14.   
  15.     // 累加已压进了几个元素  
  16.     if (! $this->_memcache->increment($this->_pushedCountKey)) {  
  17.         $this->_memcache->set($this->_pushedCountKey, 1);  
  18.     }  
  19.   
  20.     return true;  
  21. }  

pop数据:

[php] view plain copy
  1. public function pop()  
  2. {  
  3.     $poped = intval($this->_memcache->get($this->_popedCountKey));  
  4.   
  5.     // 弹出  
  6.     $key = $this->_queueDataKey . ':' . $poped;  
  7.     $value = $this->_memcache->get($key);  
  8.   
  9.     // 如队列已全部弹出,则跳出  
  10.     if ($value === false) {  
  11.         return false;  
  12.     }  
  13.   
  14.     // 从队列中删除此数据  
  15.     $this->_memcache->delete($key);  
  16.   
  17.     // 累加弹出了几个元素  
  18.     if (! $this->_memcache->increment($this->_popedCountKey)) {  
  19.         $this->_memcache->set($this->_popedCountKey, 1);  
  20.     }  
  21.   
  22.     return $value;  
  23. }  

redis实现

Redis提供了列表,可以很容易的实现队列,主要需要的函数有:

rpush($value) : 向队列中压入一个数据

lpop($value): 弹出一个数据

队列的使用范围

需要异步处理的时候,使用队列,可以缩短响应时间,比如网页发短信,可以把需要发送的短信保存在队列中,然后直接提示玩家短信发送成功,其实,这个时候短信可能还没有发送出去,发送短信的服务器再读取这个队列,然后发送短信。所以提示玩家短信发送成功和发送短信是异步处理的