memcached全面剖析

wujiuliu 贡献于2013-05-31

作者 微软用户  创建于2012-08-12 06:38:00   修改者微软用户  修改于2012-08-12 08:20:00字数5124

文档摘要:memcached 是以LiveJournal 旗下Danga Interactive 公司的Brad Fitzpatric 为首开发的一款软件。现在已成为 mixi、 hatena、 Facebook、 Vox、LiveJournal等众多服务中提高Web应用扩展性的重要因素。为了提高性能,memcached中保存的数据都存储在memcached内置的内存存储空间中。由于数据仅存在于内存中,因此重启memcached、重启操作系统会导致全部数据消失。另外,内容容量达到指定值之后,就基于LRU(Least Recently Used)算法自动删除不使用的缓存。 memcached本身是为缓存而设计的服务器,因此并没有过多考虑数据的永久性问题。
关键词:

Memcached全面剖析 1. memcached的基础 memcached是什么? memcached 是以LiveJournal 旗下Danga Interactive 公司的Brad Fitzpatric 为首开发的一款软件。现在已成为 mixi、 hatena、 Facebook、 Vox、LiveJournal等众多服务中提高Web应用扩展性的重要因素。 许多Web应 将数据保存到RDBMS(relational database management system,关系型数据库管理系统)中,应用服务器从中读取数据并在浏览器中显示。但随着数据量的增大、访问的集中,就会出现RDBMS的负担加重、数据库响应恶化、网站显示延迟等重大影响。这时就该memcached大显身手了。memcached是高性能的分布式内存缓存服务器。一般的使用目的是,通过缓存数据库查询结果,减少数据库访问次数,以提高动态Web应用的速度、提高可扩展性。 图1 一般情况下memcached的用途 memcached的特征 memcached作为高速运行的分布式缓存服务器,具有以下的特点。 · 协议简单 · 基于libevent的事件处理 · 内置内存存储方式 · memcached不互相通信的分布式 内置内存存储方式 为了提高性能,memcached中保存的数据都存储在memcached内置的内存存储空间中。由于数据仅存在于内存中,因此重启memcached、重启操作系统会导致全部数据消失。另外,内容容量达到指定值之后,就基于LRU(Least Recently Used)算法自动删除不使用的缓存。 memcached本身是为缓存而设计的服务器,因此并没有过多考虑数据的永久性问题。 memcached不互相通信的分布式 memcached尽管是“分布式”缓存服务器,但服务器端并没有分布式功能。各个memcached不会互相通信以共享信息。那么,怎样进行分布式呢?这完全取决于客户端的实现。本连载也将介绍memcached的分布式。 图2 memcached的分布式 接下来简单介绍一下memcached的使用方法。 安装memcached:memcached支持许多平台。 * Linux * FreeBSD * Solaris (memcached 1.2.5以上版本) * Mac OS X另外也能安装在Windows上。这里使用Fedora Core 8进行说明。运行memcached需要本文开头介绍的libevent库。Fedora 8中有现成的rpm包,通过yum命令安装即可。 memcached的启动:从终端输入以下命令,启动memcached。 用客户端连接:许多语言都实现了连接memcached的客户端,其中以Perl、PHP为主。仅仅memcached网站上列出的语言就有Perl PHP Python Ruby C# C/C++ Lua 等等。 2.理解memcached的内存存储 memcached默认情况下采用了名为Slab Allocator的机制分配、管理内存。在该机制出现以前,内存的分配是通过对所有记录简单地进行malloc和free来进行的。但是,这种方式会导致内存碎片,加重OS管理器的负担 Slab Allocation机制:整理内存以便重复使用 Slab Allocation的原理相当简单。 将分配的内存分割成各种尺寸的块(chunk),并把尺寸相同的块分成组(chunk的集合)(图1)。 图1 Slab Allocation的构造图 而且,slab allocator还有重复使用已分配的内存的目的。也就是说,分配到的内存不会释放,而是重复利用。 Slab Allocation的主要术语 Page:分配给Slab的内存空间,默认是1MB。分配给Slab之后根据slab的大小切分成chunk。 Chunk:用于缓存记录的内存空间。 Slab Class:特定大小的chunk的组。 memcached根据收到的数据的大小,选择最适合数据大小的slab(图2)。 memcached中保存着slab内空闲chunk的列表,根据该列表选择chunk,然后将数据缓存于其中。 图2 选择存储记录的组的方法 Slab Allocator的缺点 Slab Allocator解决了当初的内存碎片问题,但新的机制也给memcached带来了新的问题。 这个问题就是,由于分配的是特定长度的内存,因此无法有效利用分配的内存。例如,将100字节的数据缓存到128字节的chunk中,剩余的28字节就浪费了(图3)。 3.memcached的删除机制和发展方向 memcached是缓存,所以数据不会永久保存在服务器上,这是向系统中引入memcached的前提。本次介绍memcached的数据删除机制,以及memcached的最新发展方向——二进制协议(Binary Protocol)和外部引擎支持。 数据不会真正从memcached中消失:上次介绍过, memcached不会释放已分配的内存。记录超时后,客户端就无法再看见该记录(invisible,透明),其存储空间即可重复使用。 LRU:从缓存中有效删除数据的原理 memcached会优先使用已超时的记录的空间,但即使如此,也会发生追加新记录时空间不足的情况,此时就要使用名为 Least Recently Used(LRU)机制来分配空间。顾名思义,这是删除“最近最少使用”的记录的机制。因此,当memcached的内存空间不足时(无法从slab class 获取到新的空间时),就从最近未被使用的记录中搜索,并将其空间分配给新的记录。从缓存的实用角度来看,该模型十分理想。 memcached的最新发展方向 memcached的roadmap上有两个大的目标。一个是二进制协议的策划和实现,另一个是外部引擎的加载功能。 4. memcached的分布式算法 memcached的分布式 memcached虽然称为“分布式”缓存服务器,但服务器端并没有“分布式”功能。服务器端仅包括内存存储功能,其实现非常简单。至于memcached的分布式,则是完全由客户端程序库实现的。这种分布式是memcached的最大特点。 memcached的分布式是什么意思? 这里多次使用了“分布式”这个词,但并未做详细解释。现在开始简单地介绍一下其原理,各个客户端的实现基本相同。 下面假设memcached服务器有node1~node3三台,应用程序要保存键名为“tokyo”“kanagawa”“chiba”“saitama”“gunma” 的数据。 图1 分布式简介:准备 首先向memcached中添加“tokyo”。将“tokyo”传给客户端程序库后,客户端实现的算法就会根据“键”来决定保存数据的memcached服务器。服务器选定后,即命令它保存“tokyo”及其值。 图2 分布式简介:添加时 同样,“kanagawa”“chiba”“saitama”“gunma”都是先选择服务器再保存。 接下来获取保存的数据。获取时也要将要获取的键“tokyo”传递给函数库。函数库通过与数据保存时相同的算法,根据“键”选择服务器。使用的算法相同,就能选中与保存时相同的服务器,然后发送get命令。只要数据没有因为某些原因被删除,就能获得保存的值。 图3 分布式简介:获取时 这样,将不同的键保存到不同的服务器上,就实现了memcached的分布式。 Cache::Memcached的分布式方法 memcached客户端函数库Cache::Memcached是 memcached的作者Brad Fitzpatrick的作品,可以说是原装的函数库了。 · Cache::Memcached – search.cpan.org 该函数库实现了分布式功能,是memcached标准的分布式方法。 根据余数计算分散 Cache::Memcached的分布式方法简单来说,就是“根据服务器台数的余数进行分散”。求得键的整数哈希值,再除以服务器台数,根据其余数来选择服务器。 根据余数计算分散的缺点 余数计算的方法简单,数据的分散性也相当优秀,但有其缺点。那就是当添加或移除服务器时,缓存重组的代价相当巨大。添加服务器后,余数就会产生巨变,这样就无法获取与保存时相同的服务器,从而影响缓存的命中率。 例如:将“a”到“z”的键保存到memcached并访问的情况。 首先,当服务器只有三台时:结果如上,node1保存a、c、d、e……,node2保存g、i、k……,每台服务器都保存了8个到10个数据。接下来增加一台memcached服务器。 添加了node4。可见,只有d、i、k、p、r、y命中了。像这样,添加节点后键分散到的服务器会发生巨大变化。26个键中只有六个在访问原来的服务器,其他的全都移到了其他服务器。命中率降低到23%。在Web应用程序中使用memcached时,在添加memcached服务器的瞬间缓存效率会大幅度下降,负载会集中到数据库服务器上,有可能会发生无法提供正常服务的情况。 mixi的Web应用程序运用中也有这个问题,导致无法添加memcached服务器。但由于使用了新的分布式方法,现在可以轻而易举地添加memcached服务器了。这种分布式方法称为 Consistent Hashing。 Consistent Hashing的简单说明 Consistent Hashing:首先求出memcached服务器(节点)的哈希值,并将其配置到0~2SUP(32)的圆(continuum)上。然后用同样的方法求出存储数据的键的哈希值,并映射到圆上。然后从数据映射到的位置开始顺时针查找,将数据保存到找到的第一个服务器上。如果超过2SUP(32)仍然找不到服务器,就会保存到第一台memcached服务器上。 Consistent hashing的添加和删除一个服务器节点的情况不再叙述………… Consistent Hashing最大限度地抑制了键的重新分布。而且,有的Consistent Hashing的实现方法还采用了虚拟节点的思想。使用一般的hash函数的话,服务器的映射地点的分布非常不均匀。因此,使用虚拟节点的思想,为每个物理节点(服务器)在continuum上分配100~200个点。这样就能抑制分布不均匀,最大限度地减小服务器增减时的缓存重新分布。 总结 本次介绍了memcached的分布式算法,主要有memcached的分布式是由客户端函数库实现,以及高效率地分散数据的Consistent Hashing算法。 5. memcached的应用和兼容程序 随着网站访问量的急剧增加,单纯为数据库添加slave(从属)已无法满足需要,因此引入了memcached。此外,我们也从增加可扩展性的方面进行了验证,证明了memcached的速度和稳定性都能满足需要。现在,memcached已成为mixi服务中非常重要的组成部分。 由于memcached服务器几乎不占用CPU,就将换下来的服务器用作memcached服务器了。 mixi的服务将200台左右的memcached服务器作为一个pool使用。每台服务器的容量为3GB,那么全体就有了将近600GB的巨大的内存数据库。 相比Redis,Memcached 真的过时了吗? 这两年Redis火得可以,Redis也常常被当作Memcached的挑战者被提到桌面上来。关于Redis与Memcached的比较更是比比皆是。 1)没有必要过多的关心性能,因为二者的性能都已经足够高了。由于Redis只使用单核,而Memcached可以使用多核,所以在比较上,平均每一 个核上Redis在存储小数据时比Memcached性能更高。而在100k以上的数据中,Memcached性能要高于Redis,虽然Redis最近 也在存储大数据的性能上进行优化,但是比起Memcached,还是稍有逊色。说了这么多,结论是,无论你使用哪一个,每秒处理请求的次数都不会成为瓶 颈。 2)如果你对数据持久化和数据同步有所要求,那么推荐你选择Redis,因为这两个特性Memcached都不具备。即使你只是希望在升级或者重启系统后缓存数据不会丢失,选择Redis也是明智的。 3)Redis相比Memcached来说,拥有更多的数据结构和并支持更丰富的数据操作,通常在 Memcached里,你需要将数据拿到客户端来进行类似的修改再set回去。这大大增加了网络IO的次数和数据体积。在Redis中,这些复杂的操作通 常和一般的GET/SET一样高效。所以,如果你需要缓存能够支持更复杂的结构和操作,那么Redis会是不错的选择。

下载文档到电脑,查找使用更方便

文档的实际排版效果,会与网站的显示效果略有不同!!

需要 6 金币 [ 分享文档获得金币 ] 1 人已下载

下载文档