zoukankan      html  css  js  c++  java
  • 一致性hash算法(consistent hashing)

    为什么需要一致性hash

    传统hash算法常用方式为:hash(object)%N N为一个固定值。 N设置较小时容易产生冲突碰撞问题。而N设置较大时则带来开销问题。

    对于我们常用的单机程序时是内存开销变大。而用在分布式环境时,该N值和机器数目相关,则是需要的机器数增加。因此,N值应该是一个随着

    业务不断变大,而逐步提升的值。而该传统的hash算法带来的问题是N值改变,比如最初N为5,后续提升,N值改变为7

    则对应从0-13的数组取模按照该hash计算的结果如下表

      0 1 2 3 4 5 6 7 8 9 10 11 12 13
    5 0 1 2 3 4 0 1 2 3 4 0 1 2 3
    7 0 1 2 3 4 5 6 0 1 2 3 4 5 6

    通过该表我们可以明显的看出。N值改变带来的问题是hash计算的值和之前的值几乎都不同了。运用在分布式环境中,之前的机器数为5,后面增加到7

    带来的问题从该分界后面部分cache的数据失效了。这可以说是一种灾难。

    而改变该问题的就是一致性hash算法(consistent hashing)

    一致性hash的算法原理

    由于通常的hash算法我们都是对数值进行hash,而通过hash函数,我们也可以把任意的字符串转变为一个32位或者64位的数值。因此我们仍讨论对数值进行hash。

    这里以32位数值为例。其数值范围就是0-2^32-1. 之前的hash方式可以理解为将该数值看做线段的等分,如下图所示。

    image

    而一致性hash则将该区间看做一个封闭的圆环,假设最初为hash值为4(认为有4台机器)。 那么数据的划分就如下图所示,圆环分4个区间

    image

    一致性hash的基本思想是将对象和cache都映射到同一个hash数据空间。

    由于一致性hash一般都是顺时针寻找cache机器(个人认为这个顺时针逆时针不重要,把握思想即可)。因此我们数据的分布规定如下

    A机器 : 2^32/4-1

    B机器 : 2^32/2-1

    C机器: 3*2^32/4-1

    D机器: 2^32-1

    这样A机器的key范围就是[0 - 2^32/4-1] B机器的key范围是[2^32/4 - 2^32/2-1],

    C机器的key范围是[2^32/2 – 3*2^32/4-1],D机器的key范围是[3*2^32/4 – 2^32-1],

    这样给定一个值,我们顺时针找到的第一个cache,就是其需要存放的机器。

    我们插入5个key,如下图所示

    image

    此时我们讨论下当cache数变更的情况。

    场景一:cache数减少

    建设B挂掉。根据我们上面顺时针的规定。此时受影响的僵尸A到B之间的key,即上面的key2 和key3.此时这部分key需要映射到C上面。

    此时情况为:

    A机器 : 2^32/4-1

    C机器: 3*2^32/4-1

    D机器: 2^32-1

    此时 A机器的key范围就是[0 - 2^32/4-1] ,C机器的key范围是[2^32/4 – 3*2^32/4-1],D机器的key范围是[3*2^32/4 – 2^32-1],

    如下图所示。改变的只是A和B之间的,即原本存储在B机器的key。其他的不需要改变。

    image

    场景二:cache数增加

    为描述和画图方便,我们仍基于上面的4台机器的场景说明。我们增加一台机器E。机器机器变成5,此时我们假设E插入在A和B之间。此时情况应该为

    A机器 : 2^32/4-1

    E机器: 3*2^32/8-1

    B机器 : 2^32/2-1

    C机器: 3*2^32/4-1

    D机器: 2^32-1

    这样A机器的key范围就是[0 - 2^32/4-1],E机器的key范围是[2^32/4 -3^32/8-1],, B机器的key范围是[3^32/8 - 2^32/2-1],

    C机器的key范围是[2^32/2 – 3*2^32/4-1],D机器的key范围是[3*2^32/4 – 2^32-1],

    此时受影响的为逆时针方向从E到A之间的,即key2,此时只需要将key2映射到E机器即可。其他的都不需要变动。

    image

    通过上面两种场景,我们看出一致性hash 对于机器数的增加不会导致全部的cache失效,只需要改变部分key值的映射关系即可。能较好的支撑机器的改变。

    虚拟节点

    通过上面的cache数增加和减少的场景我们也发现,机器数改变时,如果不是倍数关系的改变。可能会导致不同机器承担的数据不均衡。比如上面机器数减少1时,C机器负责的范围增加,容易导致其上面的数据增多。而增加1时E和B机器的范围比其他机器都少

    针对该问题,一致性hash引入了“虚拟节点”的概念。所谓的虚拟节点就是不再根据实际的机器数,一个实际的机器节点可以对应多个虚拟节点。我们按照虚机节点对hash空间进行划分。

    引入虚机节点之后的好处是,每个节点负责的区间变小。而机器对应的是虚拟节点(可以不再是连续的一大块空间),一台机器改变时,影响的将可能不再是连续的一大块空间。从而可以将其负责的数据均摊到其他的实际机器上面。而增加机器时,可以从每个机器的虚拟节点中抽取一部分转移到新增加的机器上,以提升数据的均衡性。 在此不再详述

    refer:http://blog.csdn.net/sparkliang/article/details/5279393

    http://www.codeproject.com/Articles/56138/Consistent-hashing 一个c的实现

  • 相关阅读:
    PAT (Advanced Level) 1086. Tree Traversals Again (25)
    PAT (Advanced Level) 1085. Perfect Sequence (25)
    PAT (Advanced Level) 1084. Broken Keyboard (20)
    PAT (Advanced Level) 1083. List Grades (25)
    PAT (Advanced Level) 1082. Read Number in Chinese (25)
    HDU 4513 吉哥系列故事――完美队形II
    POJ Oulipo KMP 模板题
    POJ 3376 Finding Palindromes
    扩展KMP
    HDU 2289 Cup
  • 原文地址:https://www.cnblogs.com/sky-sql/p/6772824.html
Copyright © 2011-2022 走看看