This article will introduce to you how to use memcache to build a simple memory message queue. I will introduce it to you with a relatively good example. I hope this method will be helpful to everyone.
The memcache function is too simple. It can only set get and delete. It can only save key-value data, but cannot save lists. Of course, you can also serialize a list and store it in memcache, but there will be concurrency problems. Every time you save data (queue insertion or dequeue), the data must be locked, which is difficult to guarantee in high concurrency situations. Data consistency!
But memcache has an increment operation, which adds 1 to the value corresponding to a certain key (actually an addition operation, plus 1 by default). This operation is atomic, so we can use this to maintain an auto-incrementing ID. Ensure the uniqueness of data. Add two pointers to maintain the starting key value, and you build a simple single-phase queue! !
Upload code:
The code is as follows | Copy code |
代码如下 | 复制代码 |
/** * 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; } } |
Some things about memcached
Memory storage method (slab allocator)
The data storage method of memcached is slab allocator, which is data sharding. When the service is started, the memory is divided into chunks of different sizes. When data comes, it is stored in a chunk of appropriate size
The previous version allocates memory directly, causing problems such as memory fragmentation and random searches. . .
Data expiration deletion mechanism
Memcached will not delete the data after it expires, but it cannot access expired data, and the space occupied by expired data will be reused
Memcached uses lazy expiration. It does not actively scan whether a data item has expired, but determines whether it has expired when the data is obtained.
The deletion algorithm is LRU (Least Recently Used), which gives priority to deleting data that has been used less recently
Memcached’s distributed mechanism
Although memcached is a distributed cache, memcached itself does not implement any distributed mechanism. The distributed function is mainly implemented by the client.
The program adds multiple memcahced services to the client (memcache extension) through addserver. Before accessing data, the client will first obtain the node where the data is stored through the hash algorithm, and then access the data. When one of the memcached servers hangs up, Or if you add a new memcached server, the node where the data is stored based on the hash algorithm will change, and the new server will be used to access the data.