ketama:一致性hash
原文地址:http://www.audioscrobbler.net/development/ketama/
libketama是用c写的一致性hash库。
ketama可以对serverlist进行一致性映射,即使从list中增加或者删除server。
以前server的映射方式是:
server = serverlist[hash(key)%serverlist.length];
这种方式增加或者删除server时,所有的server的hash值都会改变,需要改变全部缓存。
Ketama的解决方式:
生成hash:
- 获取serverlist(eg: 1.2.3.4:11211, 5.6.7.8:11211, 9.8.7.6:11211)
- 将servers映射为多个无符号整数。
- 将这些数放在一个圆上。类似一个从0到2^32的“时钟”。(下文将这种数据结构称为continuum)
- 每个数都连接server。所以servers在continuum上表现为几个点。
- 将key hash为一个无符号整数,然后在continuum上顺时针找下一个点。找到的点连接的server即为需要查找的server。
- 如果到了2^32但是没有找到点,那么从0开始继续查找。
源码的定义:
typedef struct
{
int numpoints;
void* modtime;
void* array; //array of mcs structs
} continuum;
注:如下图所示,集群中的机器ABCDE通过一定的hash分布到continuum上。
分析:
1、如果在CD中插入一个新机器F。那么查找落在DF中间的key时,会正确的找到D(策略是顺时针找下一个点)。查找原来落在CF之间的key时会无法命中缓存。但比起之前mod方式hash 不命中缓存的数目已经大大降低。即只有CF段缓存不命中。
2、如果删除B节点,那么查找落在BC中间的key时,会正确的找到C。查找落在AB中间的key时因为B已经删除,会找到C。即只有AB段会出现缓存不命中。
实现细节:
server list保存在一个文件中,当这个文件改变时,libketama会重新建立continuum 。continuum是保存在共享内存中的,每当你查找key时都会使用。你可以定期获取的最新的文件,如果文件改变了,libketama将会自动修改continuum。
源码位置:
svn://svn.audioscrobbler.net/misc/ketama
-------------------------------------------------------------------------------------------------------------------------
参考文献:
http://www.iteye.com/topic/611976
http://langyu.iteye.com/blog/684087