传统的Hash算法,hash(key)之后对机器数取模,如果某个节点宕机后、或者加入新的节点,都需要进行rehash,这个时候会导致之前机器上的数据会重新分配,可能会造成雪崩。
而一致性Hash,hash值的范围为 [0,1 << 32 -1]。先将服务器放置到hash环上,比如
机器A对应的hash值为 (1 << 8) -1
机器B对应的hash值为 (1 << 16) -1
机器C对应的hash值为 (1 << 24) -1
机器D对应的hash值为 (1 << 32) -1
hash(1) = (1 << 4) -1 ,则1在hash环上顺时针查找的第一个节点为A
hash(2) = (1 << 12) -1 ,则2在hash环上顺时针查找的第一个节点为B。
如果A节点宕机了,则1在hash环上顺时针查找的第一个节点为B
如果新增了一个机器B1,hash值为 (1 << 14) -1 ,则2顺时针查找的第一个节点为B1。
可以看到采用一致性Hash后,新增或删除节点只会影响这个节点和其逆时针第一个节点对应的hash 范围内的key。容错性和扩展性更好。
为了让key分布的更均匀,还可以引入虚拟节点的概念。比如
A对应的虚拟节点有A1、A2、A3,B对应的虚拟节点有B1、B2、B3,然后对虚拟节点进行hash取值,这样让key均匀的分布在虚拟节点上,也就间接的均匀分布在物理节点上。
网友评论