博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Memcached全面剖析–3.memcached的删除机制和发展方向
阅读量:6438 次
发布时间:2019-06-23

本文共 6284 字,大约阅读时间需要 20 分钟。

以下是《memcached全面剖析》的第三部分。

发表日:2008/7/16 
作者:前坂徹(Toru Maesaka) 
原文链接:

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

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

数据不会真正从memcached中消失

介绍过, memcached不会释放已分配的内存。记录超时后,client就无法再看见该记录(invisible,透明)。 其存储空间就可以反复使用。

Lazy Expiration

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

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

memcached会优先使用已超时的记录的空间,但即使如此,也会发生追加新记录时空间不足的情况, 此时就要使用名为 Least Recently Used(LRU)机制来分配空间。 顾名思义。这是删除“近期最少使用”的记录的机制。

因此,当memcached的内存空间不足时(无法从 获取到新的空间时)。就从近期未被使用的记录中搜索。并将其空间分配给新的记录。

从缓存的有用角度来看,该模型十分理想。

只是,有些情况下LRU机制反倒会造成麻烦。memcached启动时通过“-M”參数能够禁止LRU,例如以下所看到的:

$ memcached -M -m 1024

启动时必须注意的是,小写的“-m”选项是用来指定最大内存大小的。

不指定详细数值则使用默认值64MB。

指定“-M”參数启动后,内存用尽时memcached会返回错误。 话说回来。memcached毕竟不是存储器。而是缓存,所以推荐使用LRU。

memcached的最新发展方向

memcached的roadmap上有两个大的目标。

一个是二进制协议的策划和实现,还有一个是外部引擎的载入功能。

关于二进制协议

使用二进制协议的理由是它不须要文本协议的解析处理,使得原本快速的memcached的性能更上一层楼, 还能降低文本协议的漏洞。眼下已大部分实现,开发用的代码库中已包括了该功能。

memcached的下载页面上有代码库的链接。

二进制协议的格式

协议的包为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文档。

HEADER中引人注目的地方

看到HEADER格式后我的感想是,键的上限太大了!如今的memcached规格中,键长度最大为250字节, 但二进制协议中键的大小用2字节表示。因此,理论上最大可使用65536字节(2<sup>16</sup>)长的键。

虽然250字节以上的键并不会太经常使用。二进制协议公布之后就能够使用巨大的键了。

二进制协议从下一版本号1.3系列開始支持。

外部引擎支持

我去年以前试验性地将memcached的存储层改造成了可扩展的(pluggable)。

MySQL的Brian Aker看到这个改造之后。就将代码发到了memcached的邮件列表。

memcached的开发人员也十分感兴趣,就放到了roadmap中。如今由我和 memcached的开发人员Trond Norbye协同开发(规格设计、实现和測试)。

和国外协同开发时时差是个大问题,但抱着同样的愿景, 最后最终能够将可扩展架构的原型发布了。 代码库能够从 上訪问。

外部引擎支持的必要性

世界上有很多memcached的派生软件。其理由是希望永久保存数据、实现数据冗余等, 即使牺牲一些性能也在所不惜。我在开发memcached之前,在mixi的研发部也以前 考虑过又一次发明memcached。

外部引擎的载入机制能封装memcached的网络功能、事件处理等复杂的处理。 因此,现阶段通过强制手段或又一次设计等方式使memcached和存储引擎合作的困难 就会烟消云散。尝试各种引擎就会变得轻而易举了。

简单API设计的成功的关键

该项目中我们最重视的是API设计。函数过多。会使引擎开发人员感到麻烦; 过于复杂,实现引擎的门槛就会过高。因此,最初版本号的接口函数仅仅有13个。 详细内容限于篇幅,这里就省略了,仅说明一下引擎应当完毕的操作:

  • 引擎信息(版本号等)
  • 引擎初始化
  • 引擎关闭
  • 引擎的统计信息
  • 在容量方面,測试给定记录是否能保存
  • 为item(记录)结构分配内存
  • 释放item(记录)的内存
  • 删除记录
  • 保存记录
  • 回收记录
  • 更新记录的时间戳
  • 数学运算处理
  • 数据的flush

对具体规格有兴趣的读者,能够checkout engine项目的代码。阅读器中的engine.h。

又一次审视如今的体系

memcached支持外部存储的难点是。网络和事件处理相关的代码(核心server)与 内存存储的代码紧密关联。这样的现象也称为tightly coupled(紧密耦合)。 必须将内存存储的代码从核心server中独立出来,才干灵活地支持外部引擎。

因此。基于我们设计的API,memcached被重构成以下的样子:


重构之后。我们与1.2.5版、二进制协议支持版等进行了性能对照,证实了它不会造成性能影响。

在考虑怎样支持外部引擎载入时,让memcached进行并行控制(concurrency control)的方案是最为easy的。 可是对于引擎而言,并行控制正是性能的真谛,因此我们採用了将多线程支持全然交给引擎的设计方案。

以后的改进。会使得memcached的应用范围更为广泛。

总结

本次介绍了memcached的超时原理、内部怎样删除数据等。在此之上又介绍了二进制协议和 外部引擎支持等memcached的最新发展方向。这些功能要到1.3版才会支持。敬请期待。

这是我在本连载中的最后一篇。

感谢大家阅读我的文章!

下次由长野来介绍memcached的应用知识和应用程序兼容性等内容。

原文地址:http://kb.cnblogs.com/page/42733/

你可能感兴趣的文章
Python中四种交换两个变量的值的方法
查看>>
ora-01033:oracle initialization or shutdown in progress 解决方法
查看>>
移动自动化相关名词解释
查看>>
微信开发者工具 快捷键
查看>>
monkey测试===修改adb的默认端口
查看>>
AsyncTask和Handler处理异步消息
查看>>
Scheme 中的 pair 和 list 简述
查看>>
iOS AVAssetExportSession 视频剪切、合并、压缩
查看>>
我收藏的技术知识图(每张都是大图)
查看>>
Spring Boot制作启动图案
查看>>
《Linux内核设计与实现》读书笔记(十一)- 定时器和时间管理
查看>>
hdu Oil Deposits
查看>>
彻底理解javascript中的this指针
查看>>
SAS去空格
查看>>
Spring Cloud构建微服务架构(二)服务消费者
查看>>
这些老外的开源技术养活了一票国产软件
查看>>
Maven实战(六)--- dependencies与dependencyManagement的区别
查看>>
创业者应该有的5个正常心态(转)
查看>>
php模式设计之 注册树模式
查看>>
【Android UI设计与开发】3.引导界面(三)实现应用程序只启动一次引导界面
查看>>