[转] twemproxy ketama一致性hash分析
评注:提到HAProxy业务层proxy, twemproxy存储的proxy.
其中还提到了ketama算法的实现源码
转自:http://www.cnblogs.com/basecn/p/4288456.html
测试Twemproxy集群,双主双活
向twemproxy集群做写操作时,发现key的分布不太理想。在测试节点故障时,也发现一些和预想不太一样的地方。
1、Key的一致性Hash
当尝试以a001,a002这样有规律且的key值写入的时候,在4节点的集群环境中,key主要分布在其中的2台节点,另外两台分配极少。对于一些应用来说,key值可能根据一定规则生成,所以有被定向分配的可能。
解决办法在key中使用hash_key:{},hask_key使用8位随机数,测试结果分布的比较满意。
测试4节点中key的分布:
2: 10761
3: 8596
4: 14382
由于ketama的算法仍是使用了md5签名(具体后面说),又特意观察了比如有序数字生成的md5序列,结果并没有出现明显的有序或连序值。所以只能建议不使用连续的数据结尾key做一致性hash key。
2、ketama算法
twemproxy源码下载:https://github.com/twitter/twemproxy,命令:git clone https://github.com/twitter/twemproxy
关于ketama算法的代码在nc_ketama.c文件中,主要是四个方法:
- ketama_hash 计算某个主机,某个point的hash值
- ketama_item_cmp 比较两个连续区的值,用于在ketama_update 方法中排序
- ketama_update 更新server-pool的分配策略
- ketama_dispatch 找出给定hash值所在的连续区
2.1 连续区
说一下连续区(continuum),参考下图。想象所有md5的值构成下面完整的“环”(没有起点),那么所有md5结果值在环上都有一个固定的位置。
按ketama的算法,在这个环上创建服务器数*160个点,这些点把环分成了同等数量的段。
那么,被插入数据的md5值也一定会落到环的某个区间,以此来判断数据应被写入哪台服务器。
参考:理想化的Redis集群
2.2 如何生成ketama_hash
再来看服务器+点的hash值是如何生成的:
alignment的值固定是4,ketama_hash是对由server名+索引组成的md5签名,从第16位开始取值,再重组一个32位值。

static uint32_t
ketama_hash(const char *key, size_t key_length, uint32_t alignment)
{
unsigned char results[16]; md5_signature((unsigned char*)key, key_length, results); return ((uint32_t) (results[3 + alignment * 4] & 0xFF) << 24)
| ((uint32_t) (results[2 + alignment * 4] & 0xFF) << 16)
| ((uint32_t) (results[1 + alignment * 4] & 0xFF) << 8)
| (results[0 + alignment * 4] & 0xFF);
}

下面是调用ketama_hash的代码:
for (x = 0; x < pointer_per_hash; x++) {
value = ketama_hash(host, hostlen, x);
pool->continuum[continuum_index].index = server_index;
pool->continuum[continuum_index++].value = value;
}
每个服务器被分成160个point点,由服务器名+索引组成host值,x值等于160/索引。
这样计算出的服务器各点的值并不是有序的,所以进行排序。
qsort(pool->continuum, pool->ncontinuum, sizeof(*pool->continuum), ketama_item_cmp);
排序后的点值是连续的,但同一服务器的点并不一定连续。这时,所有的值构成了用于一致性hash的环。
2.3、分配Key
由ketama_dispatch实现key值的分配。
可见方法中使用二分法找到一个值在环中的对应区域。

uint32_t
ketama_dispatch(struct continuum *continuum, uint32_t ncontinuum, uint32_t hash)
{
struct continuum *begin, *end, *left, *right, *middle; ASSERT(continuum != NULL);
ASSERT(ncontinuum != 0); begin = left = continuum;
end = right = continuum + ncontinuum; while (left < right) {
middle = left + (right - left) / 2;
if (middle->value < hash) {
left = middle + 1;
} else {
right = middle;
}
}
if (right == end) {
right = begin;
}
return right->index;
}

3、服务器的故障处理
从集群中摘除节点时,ketama的算法不会重新计算"环"。当需要写入故障节点时,会抛出异常。
仔细想一下是合理的,因为摘除的节点持有一部分数据,一般来说是需要恢复的,这是一个前提。
我们假设twemproxy可以感知节点故障,并重新计算分配策略。那么,故障后又有新的数据写入。这时,一部分原本要写入故障节点的数据会被分配到其它节点上。
随后,故障节点恢复,twemproxy又重新调整了分配策略。那么,后写入的那部分数据就不会再被找到(这个有点像内存泄露)。
[转] twemproxy ketama一致性hash分析的更多相关文章
- 【原】 twemproxy ketama一致性hash分析
转贴请注明原帖位置:http://www.cnblogs.com/basecn/p/4288456.html 测试Twemproxy集群,双主双活 向twemproxy集群做写操作时,发现key的分布 ...
- 一致性Hash 分析和实现
一致性Hash 分析和实现 ---title: 1.一致性Hashdate: 2018-02-05 12:03:22categories:- 一致性Hash--- 一下分析来源于网络总结:算法参照自己 ...
- 一致性Hash算法(KetamaHash)的c#实现
Consistent Hashing最大限度地抑制了hash键的重新分布.另外要取得比较好的负载均衡的效果,往往在服务器数量比较少的时候需要增加虚拟节点来保证服务器能均匀的分布在圆环上.因为使用一般的 ...
- SOFA 源码分析 — 负载均衡和一致性 Hash
前言 SOFA 内置负载均衡,支持 5 种负载均衡算法,随机(默认算法),本地优先,轮询算法,一致性 hash,按权重负载轮询(不推荐,已被标注废弃). 一起看看他们的实现(重点还是一致性 hash) ...
- OpenStack_Swift源代码分析——Ring基本原理及一致性Hash算法
1.Ring的基本概念 Ring是swfit中最重要的组件.用于记录存储对象与物理位置之间的映射关系,当用户须要对Account.Container.Object操作时,就须要查询相应的Ring文件( ...
- memcache的一致性hash算法使用
一.概述 1.我们的memcache客户端(这里我看的spymemcache的源码),使用了一致性hash算法ketama进行数据存储节点的选择.与常规的hash算法思路不同,只是对我们要存储数据的k ...
- 转: memcached Java客户端spymemcached的一致性Hash算法
转自:http://colobu.com/2015/04/13/consistent-hash-algorithm-in-java-memcached-client/ memcached Java客户 ...
- 一致性hash算法在memcached中的使用
一.概述 1.我们的memcacheclient(这里我看的spymemcache的源代码).使用了一致性hash算法ketama进行数据存储节点的选择.与常规的hash算法思路不同.仅仅是对我们要存 ...
- 一致性 Hash 在负载均衡中的应用
介 一致性Hash是一种特殊的Hash算法,由于其均衡性.持久性的映射特点,被广泛的应用于负载均衡领域,如nginx和memcached都采用了一致性Hash来作为集群负载均衡的方案.本文将介绍一致性 ...
随机推荐
- angular 列表渲染机制
watchCollection:监听集合元素的变化,而不能监听到集合元素内部的属性变化,只要集合中元素的引用没有发生变化,则认为无变化.用这个api也可以监听普通对象的第一层属性变化. watch:监 ...
- verdi知识点
引用:http://blog.csdn.net/naclkcl9/article/details/5425936 1. verdi 加强了active anotation, active trace和 ...
- LCD驱动分析(二)帧缓冲设备作为平台设备
参考:S3C2440 LCD驱动(FrameBuffer)实例开发<一> S3C2440 LCD驱动(FrameBuffer)实例开发<二> 1.平台设备注册 1.1在li ...
- 在 shell中, 我們可用 $0, $1, $2, $3 ... 這樣的变量分別提取命令行中变量
代码: script_name parameter1 parameter2 parameter3 ...我們很容易就能猜出 $0 就是代表 shell script 名称(路径)本身,而 $1 就是其 ...
- H.264 与 MPEG-4 压缩格式的变革
h.264 和 mpeg-4 的关系: h.264 /avc ( advanced video coding )标准,是 mpeg-4 的第 10 部分. mpeg-4的初衷是将dvd质量的图像码流从 ...
- 经典:区间dp-合并石子
题目链接 :http://acm.nyist.edu.cn/JudgeOnline/problem.php?pid=737 这个动态规划的思是,要得出合并n堆石子的最优答案可以从小到大枚举所有石子合并 ...
- JavaScript括号中什么什么不加引号什么时候加引号?
*****我的QQ号:1539832180.欢迎一起讨论学习.***** 1.如果是你定义的变量,不能加引号. 因为在大多数语言里面,单引号(或双引号)里面的内容表示的都是字符串. 2.如果是你定义的 ...
- Python第三方库之openpyxl(6)
Python第三方库之openpyxl(6) 折线图 折线图允许在固定轴上绘制数据,它们类似于散列图,主要的区别在于,在折线图中,每个数据序列都是根据相同的值绘制的,不同的轴可以用于辅助轴,与条形图类 ...
- LDP协议详解-上
MPLS基础 模式 标签分配模式(label allocation)本地为一条路由前缀绑定一个label标签的条件.独立控制模式(independent control)本地RIB学习到的路由(除BG ...
- [BZOJ2523][Ctsc2001]聪明的学生
[BZOJ2523][Ctsc2001]聪明的学生 试题描述 一位教授逻辑学的教授有三名非常善于推理且精于心算的学生A,B和C.有一天,教授给他们三人出了一道题:教授在每个人脑门上贴了一张纸条并告诉他 ...