一致性hash
Posted sunxing007
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一致性hash相关的知识,希望对你有一定的参考价值。
Hash的原理:把大范围的值域映射到小范围的值域;例如,把String映射到32位整数;String输入端变化无穷,输出端不超过2的31次方;
常见的Hash算法:
1 加法Hash,顾名思义,把输入string的每个char的code累加,然后取模;
public static int additiveHash(String key, int prime) { int hash, i; for (hash = key.length(), i = 0; i < key.length(); i++) hash += key.charAt(i); return (hash % prime); }
2 位运算Hash, 通过各种位运算混合输入项,然后取模;
public static int rotatingHash(String key, int prime) { int hash, i; for (hash = key.length(), i = 0; i < key.length(); ++i) hash = (hash << 4) ^ (hash >> 28) ^ key.charAt(i); return (hash % prime); }
3 乘法Hash,例如JDK String的hashCode;
public static int jdkHash(String data) { int h = 0; for (int i = 0; i < data.length(); i++) { h = 31 * h + data.charAt(i); } return h; }
4 除法Hash
5 混合Hash
一致性Hash的动机
在分布式系统中,如何决定一个请求应该由哪台服务器来处理,或者一条数据应该缓存在哪台服务器上;常规做法是hash取模,模数是机器数量,但是如果分布式系统中增加了节点或减少了节点,会造成所有缓存都失效。故而需要一致性的hash算法,就算分布式系统节点有所变化, 也不会对缓存命中造成太大影响;
一致性hash的原理:
1 构造一个长度为232的整数环;
2 根据节点IP获得hashCode,放到环上;
3 对于任意输入,获得hashCode,也放到环上;然后从该位置开始,顺时针找到的第一个节点即为目标节点;
一致性Hash算法的衡量标准:
平衡性: 尽可能分布到所有缓冲区, JDK的hashcode平衡性不好;
一致性:节点的增减不会带来大范围的目标节点的变化;
分散性:输入string变化很小,输出的hashcode变化要很大;从而保证相似的输入分散开,而不会聚集在某一个节点;
虚拟节点
节点的数量相对于圆环来说毕竟是很少的,这样的话极容易造成节点在圆环上不够均匀,为了解决这个问题,可对每个真实节点引入若干个虚拟节点;
以上是关于一致性hash的主要内容,如果未能解决你的问题,请参考以下文章