分布式算法——一致性哈希、一致性Hash
- 概述
- 传统Hash算法
- 算法步骤
- 生成Hash环
- 定位服务器
- 定位数据和映射服务器
- 服务器变更
- Hash环倾斜
- 虚拟节点
- 总结
概述
一致性哈希算法在1997年由麻省理工学院提出,是一种特殊的哈希算法,目的是解决分布式缓存的问题。在移除或者添加一个服务器时,能够尽可能小地改变已存在的服务请求与处理请求服务器之间的映射关系。一致性哈希解决了简单哈希算法在分布式哈希表( Distributed Hash Table,DHT) 中存在的动态伸缩等问题。
整体流程大致分为三步。
一:生成Hash环:首先,对存储节点的哈希值进行计算,其将存储空间抽象为一个环,将存储节点配置到环上。环上所有的节点都有一个值。
二:对各个服务器使用Hash函数进行哈希计算,具体可以选择服务器的IP或主机名作为关键字进行哈希,从而确定每台机器在哈希环上的位置。
二:对各个服务器使用Hash函数进行哈希计算,具体可以选择服务器的IP或主机名作为关键字进行哈希,从而确定每台机器在哈希环上的位置。
三:对数据进行哈希计算,按顺时针方向将其映射到离其最近的节点上去。当有节点出现故障离线时,按照算法的映射方法,受影响的仅仅为环上故障节点开始逆时针方向至下一个节点之间区间的数据对象,而这些对象本身就是映射到故障节点之上的。
文章中使用的动画网站地址,限 pc: 一致性哈希 算法动画
http://www.donghuasuanfa.com/platform/portal?pc=consistent-hashing
传统Hash算法
假设现在一共有3个服务器和n个数据,需要将数据存储到服务器上。那么传统的做法是将数据进行Hash算法,然后与3取模。取模结果为数据映射服务器的结果。
数据计算和定位服务器过程如下图1-1所示
映射计算结果如下图1-2所示
如果新增加一个服务器,因为服务器数量变更。则需要对n个数据重新进行映射。重新计算的过程耗时耗力。
为了解决上述问题,则发明出一致性hash算法。
算法步骤
生成Hash环
一:首先将232的节点生成一个虚拟圆环,称为Hash 环。Hash环的节点为0、1、2…232-1 。
类似钟表,钟表是12个小时节点组成的圆环。而 Hash 环是是由 232幂组成的圆环。详情如图2-1所示
定位服务器
服务器需要加入到集群中。则需要定位服务的节点位置,定位过程为通过服务器ip计算Hash结果。然后结果与232取模。结果肯定为0~232-1中的某一个数字。取模结果对应的环中的位置就是服务器的所在位置。
详情如图2-2所示
定位数据和映射服务器
现在有数据需要定位到服务器,传统的方式可以为与服务器个数进行取模预算,取模结果为映射到的服务器。例如共有3个服务器。数据与3进行取模,结果为0。则数据定位到第一个服务器。
一致性hash处理数据的步骤如下:
一:将数据进行Hash计算。计算结果与232次幂取模,取模结果定位到Hash环上。
二:通过数据所在位置,沿顺时针寻找最近的服务器,然后数据定位到对应的服务器。
详情如图2-3所示
服务器变更
现集群中有3个服务器和4个数据。其中张三、李四、王五定位的服务器为第一台红色服务器,赵六定位的服务器为第二台绿色服务器。
假设第二个服务器宕机了,则逆时针寻找宕机的服务器与存活服务器时间的数据。图中需要处理的数据为赵六数据节点。重新定位的逻辑依旧为顺时针定位寻找存活的服务器。图中赵六重新定位的结果为第3个蓝色服务器。
新增服务器时同理,只需要重新计算新服务器和新服务器逆时针顺序的第一个服务器的中间数据即可。不用全量重新计算所有数据。
详情如图3-1所示
Hash环倾斜
当环上服务器较少时,容易造成数据与服务器分布均匀。如图4-1所示。张三、李四、王五三个数据都映射到了红色服务器,但是其他服务器所对应的数据较少。这种分布不均匀的情况称为Hash环倾斜。
虚拟节点
为了解决Hash环倾斜的问题,一致性hash算法增加了虚拟节点解决问题。即对服务器节点计算多个Hash值,然后将多个Hash结果定位到Hash环上。环上的服务器节点越多,则数据映射服务器越均匀。详情如图5-1所示。
总结
-
算法解决的问题:解决集群中数据映射定位服务器,当集群中增加或减少服务器数量时,需要重新对所有数据进行计算的问题。
-
算法过程:
2.1 首先将232的节点生成一个虚拟圆环,称为Hash 环。
2.2 对服务器进行hash计算并与232进行取模计算,取模结果为hash环所在位置。
2.3 对数据进行hash计算并与232进行取模计算,然后顺时针寻找的第一个服务器为数据映射服务器。 -
服务器节点变更:只需变动新增或删除服务器与hash环上逆时针的第一个服务器之间的数据即可,无需处理所有数据。
-
Hash环倾斜:当服务器节点减少时,容易出现大量数据映射到一个服务器上。
-
虚拟节点:为了避免Hash环倾斜。所以对服务器计算多个Hash值并取模,将计算的结果映射到Hash环上。通过增加服务器的数量让数据均匀分布到服务器。