一致性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的主要内容,如果未能解决你的问题,请参考以下文章

对一致性Hash算法,Java代码实现的深入研究

对一致性Hash算法,Java代码实现的深入研究

对一致性Hash算法,Java代码实现的深入研究

对一致性Hash算法,Java代码实现的深入研究

提取jedis源码的一致性hash代码作为通用工具类

对一致性Hash算法,Java代码实现的深入研究