《memcached全面剖析》
第1章 memcached的基础
1.1 memcached是什么?
memcached是高性能的分布式内存缓存服务器。
一般的做法是,通过缓存数据库查询结果,减少数据库访问次数,以提高动态web应用的速度、可扩展性。
1.2 memcached的特征
- 协议简单:使用简单的基于文本行的协议
- 基于libevent的事件处理
- 内置内存存储方式
- memcached不互相通信的分布式:通过客户端实现分布式
1.3 安装memcached
- memcached的安装:默认安装到 /usr/local/bin 下
- memcached的启动:前台启动 /usr/local/bin/memcached -p 11211 -m 64m -vv;作为 daemon后台启动 /usr/local/bin/memcached -p 11211 -m 64m -d
1.4 用客户端连接
许多语言都实现了连接memcached的客户端,其中以Perl、PHP为主。
1.5 使用 Cache::Memcached
- 使用 Cache::Memcached 连接 Memcached
- 保存数据:向 memcached 保存数据的方法有 add,replace 和 set。向 memcached 保存数据时可以指定期限。不指定期限时,memcached 按照 LRU 算法保存数据。
- 获取数据:可以使用 get 和 get_multi 方法。
- 删除数据:使用 delete 方法。set 方法会忽视 delete 方法设置的阻塞时间,执行保存数据。
- 增一和减一操作:应注意进行错误检查。
第2章 理解 memcached 的内存存储
2.1 Slab Allocation 机制:整理内存以便重复利用
Slab Allocation 的基本原理是按照预先分配的内存大小(Page),将其分割成特定的块(Chunk),并把尺寸相同的块分成组(Slab Class),以完全解决内存碎片问题。另外,slab allocation 还能重复使用已分配的内存。
2.2 在 slab 中缓存记录的原理
memcached 根据收到的数据的大小,选择最适合数据大小的 slab,并缓存到 chunk 中。
2.3 Slab Allocation 的缺点
由于分配的是特定长度的内存,因此无法有效利用分配的内存。
2.4 使用Growth Factor 进行调优
memcached 在启动时指定 Growth Factor 因子(通过 -f 选项),就可以在某种程度上控制 slab 之间的差异。默认值为 1.25。
2.5 查看 memcached 的内部状态
使用 memcached 的 stats 命令,可以查看 slabs 的利用率等各种信息。
2.6 查看 slabs 的使用状况
第3章 memcached 的删除机制和发展方向
3.1 memcached在数据删除方面有效利用资源
- 数据不会从memcached真正消失
- Lazy Expiration:memcached不会从内部监视记录是否过期,而是在get时查看记录的时间戳,检查是否过期。
3.2 LRU:从缓存中有效删除数据的原理
3.3 memcached的最新发展方向
- 二进制协议:不需要文本协议的解析处理,提升memcached的性能和安全性。协议的包为24字节的帧,其后面是键和无结构数据。头部Header的长度为16字节,分为Request Header 和 Response Header。头部包含了表示包的有效性的Magic字节、命令种类、键长度、值长度等信息。
- 外部引擎的加载功能
3.4 外部引擎支持
- 外部引擎支持的必要性:外部引擎的加载机制能封装memcached的网络功能、事件处理等复杂操作。
- 简单API设计成功的关键
- 重新审视现在的体系:将内存存储的代码从核心服务器中独立出来,才能灵活地支持外部引擎。
第4章 memcached的分布式算法
4.1 memcached的分布式
memcached的分布式,是完全由客户端程序库实现的。
memcached的分布式是什么意思?
向memcached添加数据时,客户端的算法会根据键来选择要保存数据的memcached服务器;从memcached获取数据时,客户端会通过与数据保存时相同的算法,根据键来选择memcached服务器。
4.2 Cache::Memcached的分布式方法
根据余数计算分散
首先求得键的整数哈希值,再除以服务器台数,根据其余数来选择服务器。
当选择的服务器无法连接时,Cache::Memcached会将连接次数添加到键之后,再次计算哈希值并尝试连接。
根据余数计算分散的缺点
- 影响缓存的命中率,给数据库服务器带来极大的负载
4.3 Consistent Hashing
Consistent Hashing的简单说明
首先求出memcached服务器(节点)的哈希值,并将其配置到0~2^32的圆上,再用同样的方法求出存储数据的键的哈希值,并映射到圆上。然后从键映射到的位置开始顺时针查找,将数据保存到找到的第一个服务器上。如果超过2^32仍然找不到服务器,就会保存到第一台memcached服务器上。
在添加一台memcached服务器之后,只有在圆上增加服务器的地点和逆时针方向第一台服务器之间的键会受到影响。
如果使用虚拟节点的思想,为每个物理节点在圆上分配100~200个点,就能抑制服务器的分布不均匀,最大限度地减小服务器增减时的缓存重新分布。
支持Consistent Hashing的函数库
PHP客户端:libketama
Perl客户端:Cache::Memcached::Fast和Cache::Memcached::libmemcached
第5章 memcached的应用和兼容程序
5.1 mixi案例研究
随着网站访问量的急剧增加,单纯为数据库添加slave已经无法满足需要,因此引入了memcached。
服务器配置和数量
将数据库服务器、应用服务器等换成性能更强大、内存更多的服务器,这样可以抑制服务器数量的剧增,降低管理成本,还可以将换下来的服务器用作memcached服务器。
memcached进程
每台memcached服务器仅启动一个memcached进程。memcached进程的实际内存分配量要比指定的容量大。
memcached使用方法和客户端
现在mixi的服务将200台左右的memcached服务器作为一个pool使用。每台服务器的容量为3GB,那么就有了将近600GB的巨大内存数据库。
通过Cache::memcached::Fast维持连接
公共数据的处理和rehash
Cache::memcached::Fast会在连接服务器失败时,短时间内不再连接该服务器。
mixi还为公共数据的键名设置命名规则,符合命名规则的键名的数据会保存到多台服务器中,取数据时仅从其中一台服务器选取即可。
5.2 memcached应用经验
通过daemontools启动
daemontools可以监视memcached进程,在memcached进程死掉后自动启动它。
监视
memcached的性能
5.3 兼容应用程序
- repcached
- Flared
- memcachedb
- Tokyo Tyrant