[Memcached]Memcached 的删除机制和发展方向

        本文部分内容转载自 memcached的删除机制和发展方向 ,仅供学习使用。

        Memcached 是缓存,所以数据不会永久保存在服务器上,这是向系统中引入 Memcached 的前提。本次介绍 Memcached 的数据删除机制,以及 Memcached 的最新发展方向——二进制协议(Binary Protocol)。

Memcached 在数据删除方面有效利用资源

        1. 数据不会真正从 Memcached 中消失

        上次介绍过,Memcached 不会释放已分配的内存。记录超时后,客户端就无法再看见该记录(invisible,透明),其存储空间即可重复使用。

        2. Lazy Expiration

        Memcached 内部不会监视记录是否过期,而是在 get 时查看记录的时间戳,检查记录是否过期。这种技术被称为 lazy(惰性)expiration。因此,Memcached 不会在过期监视上耗费 CPU 时间。

LRU:从缓存中有效删除数据的原理

        Memcached 会优先使用已超时的记录的空间,但即使如此,也会发生追加新记录时空间不足的情况,此时就要使用名为 Least Recently Used(LRU)机制来分配空间。顾名思义,这是删除“最近最少使用”的记录的机制。因此,当 Memcached 的内存空间不足时(无法从 Slab Class 获取到新的空间时),就从最近未被使用的记录中搜索,并将其空间分配给新的记录。从缓存的实用角度来看,该模型十分理想。

        不过,有些情况下 LRU 机制反倒会造成麻烦。Memcached 启动时通过“-M”参数可以禁止 LRU,如下所示:

$ memcached -M -m 1024

        启动时必须注意的是,小写的“-m”选项是用来指定最大内存大小的。不指定具体数值则使用默认值 64MB。指定“-M”参数启动后,内存用尽时 Memcached 会返回错误。话说回来,Memcached 毕竟不是存储器,而是缓存,所以推荐使用 LRU。

Memcached的最新发展方向

        Memcached 的 roadmap 上有两个大的目标。一个是二进制协议的策划和实现,另一个是外部引擎的加载功能。

        1. 关于二进制协议

        使用二进制协议的理由是它不需要文本协议的解析处理,使得原本高速的 Memcached 的性能更上一层楼,还能减少文本协议的漏洞。目前已大部分实现,开发用的代码库中已包含了该功能。Memcached 的下载页面上有代码库的链接。

        2. 二进制协议的格式

        协议的包为 24 字节的帧,其后面是键和无结构数据(Unstructured Data)。实际的格式如下(引自协议文档):

 Byte/     0       |       1       |       2       |       3       |   
    /              |               |               |               |   
   |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|
   +---------------+---------------+---------------+---------------+
  0/ HEADER                                                        /   
   /                                                               /   
   /                                                               /   
   /                                                               /   
   +---------------+---------------+---------------+---------------+
 24/ COMMAND-SPECIFIC EXTRAS (as needed)                           /   
  +/  (note length in th extras length header field)               /   
   +---------------+---------------+---------------+---------------+
  m/ Key (as needed)                                               /   
  +/  (note length in key length header field)                     /   
   +---------------+---------------+---------------+---------------+
  n/ Value (as needed)                                             /   
  +/  (note length is total body length header field, minus        /   
  +/   sum of the extras and key length body fields)               /   
   +---------------+---------------+---------------+---------------+
  Total 24 bytes

        如上所示,包格式十分简单。需要注意的是,占据了 16 字节的头部(HEADER)分为请求头(Request Header)和响应头(Response Header)两种。头部中包含了表示包的有效性的 Magic 字节、命令种类、键长度、值长度等信息,格式如下:

        Request Header:

 Byte/     0       |       1       |       2       |       3       |
    /              |               |               |               |
   |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|
   +---------------+---------------+---------------+---------------+
  0| Magic         | Opcode        | Key length                    |
   +---------------+---------------+---------------+---------------+
  4| Extras length | Data type     | Reserved                      |
   +---------------+---------------+---------------+---------------+
  8| Total body length                                             |
   +---------------+---------------+---------------+---------------+
 12| Opaque                                                        |
   +---------------+---------------+---------------+---------------+
 16| CAS                                                           |
   |                                                               |
   +---------------+---------------+---------------+---------------+
        Response Header:

 Byte/     0       |       1       |       2       |       3       |
    /              |               |               |               |
   |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|
   +---------------+---------------+---------------+---------------+
  0| Magic         | Opcode        | Key Length                    |
   +---------------+---------------+---------------+---------------+
  4| Extras length | Data type     | Status                        |
   +---------------+---------------+---------------+---------------+
  8| Total body length                                             |
   +---------------+---------------+---------------+---------------+
 12| Opaque                                                        |
   +---------------+---------------+---------------+---------------+
 16| CAS                                                           |
   |                                                               |
   +---------------+---------------+---------------+---------------+

        如希望了解各个部分的详细内容,可以 checkout 出 Memcached 的二进制协议的代码树,参考其中的 docs 文件夹中的 protocol_binary.txt 文档。

        3. HEADER 中引人注目的地方

        看到 HEADER 格式后我的感想是,键的上限太大了!现在的 Memcached 规格中,键长度最大为 250 字节,但二进制协议中键的大小用 2 字节表示。因此,理论上最大可使用 65536 字节(2^16)长的键。尽管 250 字节以上的键并不会太常用,二进制协议发布之后就可以使用巨大的键了。

        二进制协议从版本 1.3 系列开始支持。

你可能感兴趣的:(Memcached)