memcached是缓存Cache所以数据不会永久保存在服务器上这是向系统中引入memcached前提本次介绍memcached数据删除机制以及memcached最新发展方向—— 2进制协议(Binary Protocol)和外部引擎支持
memcached在数据删除方面有效利用资源数据不会真正从memcached中消失 上次介绍过 memcached不会释放已分配内存记录超时后客户端就无法再看见该记录(invisible透明)其存储空间即可重复使用
Lazy Expiration memcached内部不会监视记录是否过期而是在get时查看记录时间戳检查记录是否过期这种技术被称为lazy(惰性)expiration因此memcached不会在过期监视上耗费CPU时间
LRU:从缓存Cache中有效删除数据原理 memcached会优先使用已超时记录空间但即使如此也会发生追加新记录时空间不足情况此时就要使用名为 Least Recently Used(LRU)机制来分配空间顾名思义这是删除“最近最少使用”记录机制因此当memcached内存空间不足时(无法从slab 获取到新空间时)就从最近未被使用记录中搜索并将其空间分配给新记录从缓存Cache实用角度来看该模型十分理想
不过有些情况下LRU机制反倒会造成麻烦memcached启动时通过“-M”参数可以禁止LRU如下所示:
$ memcached -M -m 1024
启动时必须注意是小写“-m”选项是用来指定最大内存大小不指定具体数值则使用默认值64MB指定“-M”参数启动后内存用尽时memcached会返回话说回来memcached毕竟不是存储器而是缓存Cache所以推荐使用LRU
memcached最新发展方向 memcachedroadmap上有两个大目标个是 2进制协议策划和实现另个是外部引擎加载功能
有关 2进制协议 使用 2进制协议理由是它不需要文本协议解析处理使得原本高速memcached性能更上层楼还能减少文本协议漏洞目前已大部分实现开发用代码库中已包含了该功能 memcached下载页面上有代码库链接
http://danga.com/memcached/download.bml
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 s
如上所示包格式十分简单需要注意是占据了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 2进制协议代码树参考其中docs文件夹中protocol_binary.txt文档HEADER中引人注目地方 看到HEADER格式后我感想是键上限太大了!现在memcached规格中键长度最大为250字节但 2进制协议中键大小用2字节表示因此理论上最大可使用65536字节(2<sup>16</sup>)长键尽管250字节以上键并不会太常用 2进制协议发布的后就可以使用巨大键了
2进制协议从下版本1.3系列开始支持
外部引擎支持 我去年曾经试验性地将memcached存储层改造成了可扩展(pluggable)
http://alpha.mixi.co.jp/blog/?p=129
MySQLBrian Aker看到这个改造的后就将代码发到了memcached邮件列表 memcached开发者也十分感兴趣就放到了roadmap中现在由我和 memcached开发者Trond Norbye协同开发(规格设计、实现和测试)和国外协同开发时时差是个大问题但抱着相同愿景最后终于可以将可扩展架构原型公布了代码库可以从memcached下载页面 上访问
外部引擎支持必要性 世界上有许多memcached派生软件Software其理由是希望永久保存数据、实现数据冗余等即使牺牲些性能也在所不惜我在开发memcached的前在mixi研发部也曾经考虑过重新发明memcached
外部引擎加载机制能封装memcached网络功能、事件处理等复杂处理因此现阶段通过强制手段或重新设计等方式使memcached和存储引擎合作困难就会烟消云散尝试各种引擎就会变得轻而易举了
简单API设计成功关键 该项目中我们最重视是API设计过多会使引擎开发者感到麻烦;过于复杂实现引擎门槛就会过高因此最初版本接口只有13个具体内容限于篇幅这里就省略了仅介绍说明下引擎应当完成操作:
引擎信息(版本等)
引擎化
引擎关闭
引擎统计信息
在容量方面测试给定记录能否保存
为item(记录)结构分配内存
释放item(记录)内存
删除记录
保存记录
回收记录
更新记录时间戳
数学运算处理
数据flush
对详细规格有兴趣读者可以checkout engine项目代码阅读器中engine.h
重新审视现在体系 memcached支持外部存储难点是网络和事件处理相关代码(核心服务器)和内存存储代码紧密关联这种现象也称为tightly coupled(紧密耦合)必须将内存存储代码从核心服务器中独立出来才能灵活地支持外部引擎因此基于我们设计APImemcached被重构成下面样子:
重构的后我们和1.2.5版、 2进制协议支持版等进行了性能对比证实了它不会造成性能影响
在考虑如何支持外部引擎加载时让memcached进行并行控制(concurrency control)方案是最为容易但是对于引擎而言并行控制正是性能真谛因此我们采用了将多线程支持完全交给引擎设计方案
以后改进会使得memcached应用范围更为广泛
整理总结 本次介绍了memcached超时原理、内部如何删除数据等在此的上又介绍了 2进制协议和外部引擎支持等memcached最新发展方向这些功能要到1.3版才会支持敬请期待!
这是我在本连载中最后篇感谢大家阅读我文章!
下次由长野来介绍memcached应用知识和应用兼容性等内容
作者:前坂徹(Toru Maesaka)
原文链接:http://gihyo.jp/dev/feature/01/memcached/0003
最新评论