下面q篇文章写的非常好,l合memcached?特点利用Consistent hasning 法Q可以打造一个非常完备的分布式缓存服务器?/p>
正如W?ơ中介绍的那P memcached虽然UCؓ“分布?#8221;~存服务器,但服务器端ƈ没有“分布?#8221;功能?服务器端仅包?W?ơ?W??前坂介绍的内存存储功能,其实现非常简单?至于memcached的分布式Q则是完全由客户端程序库实现的?q种分布式是memcached的最大特炏V?/p>
q里多次使用?#8220;分布?#8221;q个词,但ƈ未做详细解释?现在开始简单地介绍一下其原理Q各个客L的实现基本相同?/p>
下面假设memcached服务器有node1~node3三台Q?应用E序要保存键名ؓ“tokyo”“kanagawa”“chiba”“saitama”“gunma” 的数据?/p>
? 分布式简介:准备
首先向memcached中添?#8220;tokyo”。将“tokyo”传给客户端程序库后, 客户端实现的法׃Ҏ“?#8221;来决定保存数据的memcached服务器?服务器选定后,卛_令它保存“tokyo”及其倹{?/p>
? 分布式简介:d?/p>
同样Q?#8220;kanagawa”“chiba”“saitama”“gunma”都是先选择服务器再保存?/p>
接下来获取保存的数据。获取时也要要获取的键“tokyo”传递给函数库?函数库通过与数据保存时相同的算法,Ҏ“?#8221;选择服务器?使用的算法相同,p选中与保存时相同的服务器Q然后发送get命o?只要数据没有因ؓ某些原因被删除,p获得保存的倹{?/p>
? 分布式简介:获取?/p>
q样Q将不同的键保存C同的服务器上Q就实现了memcached的分布式?memcached服务器增多后Q键׃分散Q即使一台memcached服务器发生故?无法q接Q也不会影响其他的缓存,pȝ依然能l运行?/p>
接下来介l?a style="color: rgb(51,102,153); text-decoration: none" >W??/a> 中提到的Perl客户端函数库Cache::Memcached实现的分布式Ҏ?/p>
Perl的memcached客户端函数库Cache::Memcached?memcached的作者Brad Fitzpatrick的作品,可以说是原装的函数库了?/p>
该函数库实现了分布式功能Q是memcached标准的分布式Ҏ?/p>
Cache::Memcached的分布式Ҏ单来_是“Ҏ服务器台数的余数q行分散”?求得键的整数哈希|再除以服务器台数Q根据其余数来选择服务器?/p>
下面Cache::Memcached化成以下的Perl脚本来进行说明?/p>
Cache::Memcached在求哈希值时使用了CRC?/p>
首先求得字符串的CRC|Ҏ该值除以服务器节点数目得到的余数决定服务器?上面的代码执行后输入以下l果Q?/p>
tokyo => node2
kanagawa => node3
chiba => node2
saitama => node1
gunma => node1
Ҏ该结果,“tokyo”分散到node2Q?#8220;kanagawa”分散到node3{?多说一句,当选择的服务器无法q接ӞCache::Memcached会将q接ơ数 d到键之后Q再ơ计哈希值ƈ试q接。这个动作称为rehash?不希望rehash时可以在生成Cache::Memcached对象时指?#8220;rehash => 0”选项?/p>
余数计算的方法简单,数据的分散性也相当优秀Q但也有其缺炏V?那就是当d或移除服务器Ӟ~存重组的代L当巨大?d服务器后Q余数就会生巨变,q样无法获取与保存时相同的服务器, 从而媄响缓存的命中率。用Perl写段代码来验证其代h?/p>
q段Perl脚本演示了将“a”?#8220;z”的键保存到memcachedq访问的情况?其保存为mod.plq执行?/p>
首先Q当服务器只有三台时Q?/p>
l果如上Qnode1保存a、c、d、e……Qnode2保存g、i、k……Q?每台服务器都保存?个到10个数据?/p>
接下来增加一台memcached服务器?/p>
d了node4。可见,只有d、i、k、p、r、y命中了。像q样Q添加节点后 键分散到的服务器会发生巨大变化?6个键中只有六个在讉K原来的服务器Q?其他的全都移C其他服务器。命中率降低?3%。在Web应用E序中用memcachedӞ 在添加memcached服务器的瞬间~存效率会大q度下降Q负载会集中到数据库服务器上Q?有可能会发生无法提供正常服务的情c?/p>
mixi的Web应用E序q用中也有这个问题,D无法dmemcached服务器?但由于用了新的分布式方法,现在可以轻而易丑֜dmemcached服务器了?q种分布式方法称?Consistent Hashing?/p>
关于Consistent Hashing的思想Qmixi株式会社的开发blog{许多地斚w介绍q, q里只简单地说明一下?/p>
Consistent Hashing如下所C:首先求出memcached服务器(节点Q的哈希| q将光|到0?32的圆QcontinuumQ上?然后用同LҎ求出存储数据的键的哈希|q映到圆上?然后从数据映到的位|开始顺旉查找Q将数据保存到找到的W一个服务器上?如果过232仍然找不到服务器Q就会保存到W一台memcached服务器上?/p>
? Consistent HashingQ基本原?/p>
从上囄状态中d一台memcached服务器。余数分布式法׃保存键的服务器会发生巨大变化 而媄响缓存的命中率,但Consistent Hashing中,只有在continuum上增加服务器的地炚w时针方向的 W一台服务器上的键会受到影响?/p>
? Consistent HashingQ添加服务器
因此QConsistent Hashing最大限度地抑制了键的重新分布?而且Q有的Consistent Hashing的实现方法还采用了虚拟节点的思想?使用一般的hash函数的话Q服务器的映地点的分布非常不均匀?因此Q用虚拟节点的思想Qؓ每个物理节点Q服务器Q?在continuum上分?00?00个点。这样就能抑制分布不均匀Q?最大限度地减小服务器增减时的缓存重新分布?/p>
通过下文中介l的使用Consistent Hashing法的memcached客户端函数库q行试的结果是Q?由服务器台数QnQ和增加的服务器台数QmQ计增加服务器后的命中率计公式如下:
(1 - n/(n+m)) * 100
本连载中多次介绍的Cache::Memcached虽然不支持Consistent HashingQ?但已有几个客L函数库支持了q种新的分布式算法?W一个支持Consistent Hashing和虚拟节点的memcached客户端函数库?名ؓlibketama的PHP库,由last.fm开发?/p>
至于Perl客户端,q蝲的第1?中介l过的Cache::Memcached::Fast和Cache::Memcached::libmemcached支持 Consistent Hashing?/p>
两者的接口都与Cache::Memcached几乎相同Q如果正在用Cache::MemcachedQ?那么可以方便地替换q来。Cache::Memcached::Fast重新实现了libketamaQ?使用Consistent Hashing创徏对象时可以指定ketama_points选项?/p>
my $memcached = Cache::Memcached::Fast->new({
servers => ["192.168.0.1:11211","192.168.0.2:11211"],
ketama_points => 150
});
另外QCache::Memcached::libmemcached 是一个用了Brain Aker开发的C函数库libmemcached的Perl模块?libmemcached本n支持几种分布式算法,也支持Consistent HashingQ?其Perll定也支持Consistent Hashing?/p>
本次介绍了memcached的分布式法Q主要有memcached的分布式是由客户端函数库实现Q?以及高效率地分散数据的Consistent Hashing法。下ơ将介绍mixi在memcached应用斚w的一些经验, 和相关的兼容应用E序?/p>