`

memcached完全剖析 - 3.memcached的删除机制和发展方向

阅读更多

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

发表日:2008/7/16
作者:前坂徹(Toru Maesaka)
原文链接:http://gihyo.jp/dev/feature/01/memcached/0003

前几次的文章在这里:

<!-- end Pukiwiki generated code-->

 

<!-- begin Pukiwiki generated code-->

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

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

数据不会真正从memcached中消失

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

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上有两个大的目标。一个是二进制协议的策划和实现,另一个是外部引擎的加载功能。

关于二进制协议

使用二进制协议的理由是它不需要文本协议的解析处理,使得原本高速的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的派生软件,其理由是希望永久保存数据、实现数据冗余等,即使牺牲一些性能也在所不惜。我在开发memcached之前,在mixi的研发部也曾经考虑过重新发明memcached。

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

简单API设计的成功的关键

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

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

对详细规格有兴趣的读者,可以checkout engine项目的代码,阅读器中的engine.h。

重新审视现在的体系

memcached支持外部存储的难点是,网络和事件处理相关的代码(核心服务器)与内存存储的代码紧密关联。这种现象也称为tightly coupled(紧密耦合)。必须将内存存储的代码从核心服务器中独立出来,才能灵活地支持外部引擎。因此,基于我们设计的API,memcached被重构成下面的样子:

memcached-0003-001.png

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

在考虑如何支持外部引擎加载时,让memcached进行并行控制(concurrency control)的方案是最为容易的,但是对于引擎而言,并行控制正是性能的真谛,因此我们采用了将多线程支持完全交给引擎的设计方案。

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

总结

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

这是我在本连载中的最后一篇。感谢大家阅读我的文章!

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

<!-- end Pukiwiki generated code-->
分享到:
评论

相关推荐

    memcached-1.5.11.tar.gz

    《深入理解Memcached:基于1.5.11版本的剖析》 Memcached,一个高性能、分布式的内存对象缓存系统,广泛应用于Web应用中,用于减轻数据库的负载,提高数据访问速度。本文将深入探讨Memcached的1.5.11版本,解析其...

    hibernate-memcached-1.1.0-sources.zip

    《Hibernate与Memcached整合详解——基于hibernate-memcached-1.1.0源码分析》 在当今的Web开发领域,数据持久化是一个必不可少的环节,而Hibernate作为Java领域广泛使用的对象关系映射(ORM)框架,极大地简化了...

    memcached-session-manager集成包

    5. **reflectasm-1.09-shaded.jar** 和 **asm-3.2.jar**:ReflectASM是一个轻量级、高性能的Java反射库,而ASM是一个底层的Java字节码操作和分析框架。这两个库通常用于类的动态生成和修改,可能在序列化过程中发挥...

    Python库 | tencentcloud-sdk-python-memcached-3.0.556.tar.gz

    3. **事务处理**:虽然Memcached本身不支持事务,但SDK可能提供了类似的功能,以简化编程。 4. **统计与监控**:获取Memcached服务器的运行状态和统计信息,帮助优化应用性能。 5. **异常处理**:提供错误处理机制,...

    memcached-session-manager-1.8.1

    《深入理解Memcached Session Manager 1.8.1》 在Web开发中,session管理是一项至关重要的任务,它涉及到用户状态的保持与跨请求的数据共享。Memcached Session Manager(MSM)是Java环境下的一种解决方案,它利用...

    memcached-1.5.4

    **memcached-1.5.4源码分析与编译指南** `memcached`是一款高性能、分布式的内存对象缓存系统,广泛应用于Web应用中,用于减轻数据库负载,提高数据访问速度。它通过将数据存储在内存中,实现快速读取,避免了频繁...

    Python库 | tencentcloud-sdk-python-memcached-3.0.335.tar.gz

    2. 数据存取:通过SDK,可以便捷地将数据存储到Memcached中,并随时检索出来,支持键值对的设置、获取和删除操作。 3. 监控与报警:监控Memcached实例的运行状态,设置阈值报警,以便在性能下降或异常时及时采取措施...

    memcached(十一)memcached-session-manager

    **标题解析:** "memcached(十一)memcached-session-manager" 这个标题指的是一个关于memcached缓存系统与...通过这个教程,读者将能够掌握如何利用memcached作为session存储机制,提升Web应用的效率和可靠性。

    memcached-1.4.0-rc1.tar.gz

    《深入解析memcached 1.4.0:源码剖析与应用实践》 Memcached是一款高性能、分布式的内存对象缓存系统,广泛应用于Web应用中,以减轻数据库负载,提高数据访问速度。本文将深入探讨memcached 1.4.0 release ...

    redis-2.4.16.tar.gz

    相比于Memcached,Redis提供了更丰富的数据结构和更强大的持久化选项。与MongoDB等文档数据库相比,Redis更适合处理小而频繁的数据,且在内存管理上更为高效。 五、安装与使用 "redis-2.4.16.tar.gz"解压后,包含源...

    nginx-sticky-module-ng-1.2.6.tar.gz

    **Nginx Sticky Module Ng 1.2.6 源码分析与应用** Nginx 是一款高性能、轻量级的 HTTP 和反向代理服务器,广泛用于网站部署和负载均衡。在某些应用场景中,例如在线购物车、游戏服务器或者需要保持用户会话一致性...

    tomcat8+memcached session共享

    标题中的“tomcat8+memcached session共享”指的是在Tomcat 8服务器中利用Memcached进行session共享的技术实践。在分布式系统中,session共享是一个重要的问题,因为用户在访问不同的服务器节点时,需要保持登录状态...

    memcached全面剖析.zip

    memcached全面剖析, 密码 1234!... memcached的删除机制和发展方向 memcached全面剖析–4. memcached的分布式算法 memcached全面剖析–5. memcached的应用和兼容程序 可关注公众号:Java与大数据进阶

    memcached-session-manager_4_tomcat8

    3. **Memcached-Session-Manager**:这是用于Tomcat的第三方模块,使得可以将用户的session数据存储在memcached服务器上,实现session的分布式管理,适合多服务器环境,提供高可用性和负载均衡。 4. **Java 1.8**:...

    lnmp1.0-full.tar.gz安装包

    3. 监控与日志:设置监控工具(如Nagios、Zabbix)检查服务器状态,定期清理和分析Nginx、PHP、MySQL的日志。 4. 数据备份:定期备份MySQL数据库,以防数据丢失。 六、扩展与升级 随着业务需求的变化,可能需要添加...

    memcached全面剖析–3.memcached的删除机制和发展方向

    本次介绍memcached的数据删除机制,以及memcached的最新发展方向——二进制协议(Binary Protocol)和外部引擎支持。上次介绍过,memcached不会释放已分配的内存。记录超时后,客户端就无法再看见该记录(invisible...

    ehcache-server-1.0.0-distribution.tar.gz

    另外,"Ehcache还是Memcached的抉择(二)-Java技术文档 - diybl.files" 和 "Ehcache还是Memcached的抉择(一)-Java技术文档 - diybl.files" 可能是相关文档的资源文件,可能包含图表、代码示例或其他辅助材料,以...

    memcached学习资料----下载不扣分,回帖加1分,欢迎下载,童叟无欺

    │ alisoft-xplatform-asf-cache-2.4.jar │ list.txt │ Memcached+Study.pdf │ memcached全面剖析.zip │ └─memcached全面剖析 memcached.pdf

    memcached全面剖析–4. memcached的分布式算法.txt

    memcached全面剖析–4. memcached的分布式算法.txt

    CGI-SpeedyCGI-2.22.tar.gz

    CGI(Common Gateway Interface,通用网关接口)是一种在Web服务器和动态生成内容的服务器端程序之间通信的标准协议。SpeedyCGI是针对CGI的一种优化实现,它旨在提高CGI程序的性能,减少资源消耗,尤其对于处理大量...

Global site tag (gtag.js) - Google Analytics