本文章來給各位同學介紹使用memcache構建簡單的內存消息隊列,用一個比較不錯的實例來給大家介紹,希望此方法對大家有幫助哦。
memcache功能太簡單了,只能 set get 和delete, 只能保存key-value的數據, 不能保存列表。 當然也可以把一個列表給序列化了之後存進memcache, 但是會存在並發的問題, 每次保存數據(插隊或者出隊)的時候都要給數據加鎖,在高並發的情況下很難保證數據的一致性!
但是memcache 有一個 increment 的操作,為某一個鍵對應的值進行加1(實際上是加法運算, 默認加1), 這個操作是原子性的, 所以我們可以通過這個來維護一個自增的id來保證數據的唯一。 再加上兩個指針來維護起始鍵值, 這樣就構建了一個簡單的但相隊列!!
上代碼:
代碼如下
復制代碼
<?php
/**
* memcache構建的簡單內存隊列
*
* @author: jeffjing
*/
class memList {
private $memcache; // memcache類
private $queKeyPrefix; //數據鍵前綴
private $startKey; //開始指針鍵
private $startKey; //結束指針鍵
public function __construct($key){
$this->queKeyPrefix = "MEMQUE_{$key}_";
$this->startKey = "MEMQUE_SK_{$key}";
$this->endKey = "MEMQUE_EK_{$key}";
}
/**
* 獲取列表
* 先拿到開始結束指針, 然後去拿數據
*
* @return array
*/
public function getList(){
$startP = $this->memcache->get($this->startKey);
$endP = $this->memcache->get($this->endKey);
empty($startP) && $startP = 0;
empty($endP) && $endP = 0;
$arr = array();
for($i = $startP ; $i < $endP; ++$i) {
$key = $this->queKeyPrefix . $i;
$arr[] = $this->memcache->get($key);
}
return $arr;
}
/**
* 插入隊列
* 結束指針後移,拿到一個自增的id
* 再把值存到指針指定的位置
*
* @return void
*/
public function in($value){
$index = $this->memcache->increment($this->endKey);
$key = $this->queKeyPrefix . $index;
$this->memcache->set($key, $value);
}
/**
* 出隊
* 很簡單, 把開始值取出後開始指針後移
*
* @return mixed
*/
public function out(){
$result = $this->memcache->get($this->startKey);
$this->memcache->increment($this->startKey);
return $result;
}
}
關於memcached的一些事情
內存存儲方式(slab allocator)
memcached的數據存儲方式為slab allocator即數據分片, 在服務啟動的時候先把內存分成不同大小的 chunk, 當有數據過來的時候來存儲到一個合適大小的chunk當中
之前版本是直接分配內存, 導致內存碎片 隨機查找等問題。。。
數據過期刪除機制
memcached在數據過期之後,並不會去刪除數據, 但是不能訪問過期的數據, 過期數據占用的空間會被重復利用
memcached采用lazy expiration.不會去主動掃描一個數據項是否過期, 而是在數據get的時候判斷是否已經過期.
刪除的算法是LRU(Least Recently Used) , 優先刪除最近使用較少的數據
memcached的分布式機制
雖說memcached是一個分布式的緩存, 但是memcached本身並沒有實現任何分布式的機制, 分布式的功能主要是由客戶端來實現的。
程序通過addserver增加多個memcahced服務到客戶端(memcache擴展), 在存取數據之前,客戶端會先通過hash算法得到存儲數據的節點, 然後再去存取數據, 當其中一台memcached服務器掛掉或者新增一台memcached服務器, hash算法得到的存儲數據的節點就會變化, 去新的服務器上去存取數據。