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);
- }
- /**
- * 出队
- * 很简单, 把开始值取出后开始指针后移
- *// 开源代码 phprm.com
- * @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 算法得到的存储数据的节点就会变化, 去新的服务器上去存取数据.
来源: https://www.php1.cn/detail/php-83e1a5742e.html