一致性哈希是什么,使用场景,解决了什么问题?

如何分配请求

现在有那么多个节点,要如何分配客户端的请求呢?

最简单的方式,引入一个中间的负载均衡层,让它将外界的请求「轮流」的转发给内部的集群。但是加权轮询算法是无法应对「分布式系统」的,因为分布式系统中,每个节点存储的数据是不同的。

因此,我们要想一个能应对分布式系统的负载均衡算法。

使用哈希算法有什么问题?

我们想到了哈希算法。因为对同一个关键字进行哈希计算,每次计算都是相同的值,这样就可以将某个 key 确定到一个节点了,可以满足分布式系统的负载均衡需求。

哈希算法最简单的做法就是进行取模运算,比如分布式系统中有3个节点,基于 hash(key) % 3 公式对数据进行了映射。

但是有一个很致命的问题,如果节点数量发生了变化,也就是在对系统做扩容或者缩容时,必须迁移改变了映射关系的数据,否则会出现查询不到数据的问题。

假设总数据条数为M,哈希算法在面对节点数量变化时,最坏情况下所有数据都需要迁移,所以它的数据迁移规模是 O(M),这样数据的迁移成本太高了。

一致性哈希算法

一致性哈希算法就很好地解决了分布式系统在扩容或者缩容时,发生过多的数据迁移的问题。

一致哈希算法也用了取模运算,但与哈希算法不同的是,哈希算法是对节点的数量进行取模运算,而一致哈希算法是对 2^32 进行取模运算,是一个固定的值。

数据的id通过哈希函数转换成的哈希值在0 ~ 2^32-1的数字空间中,现在把这些数字头尾相连,想象成一个闭合的环形,那么一个数据id在计算出哈希值之后认为对应到环中的一个位置上。

接下来想象有三台机器也处在这样一个环中,这三台机器在环中的位置根据机器id计算出的哈希值来决定。

确定一条数据归属哪台机器,首先把该数据的id用哈希函数算出哈希值,并映射到环中的相应位置,然后顺时针找寻离这个位置最近的机器,那台机器就是该数据的归属。
比如下图中的key-01映射的位置,往顺时针的方向找到第一个节点就是节点A。

对指定key的值进行读写的地址:

  • 首先,对key进行哈希计算,确定此key在环上的位置;
  • 然后,从这个位置沿着顺时针方向走,遇到的第一节点就是存储key的节点。

增加一个节点或者减少一个节点

假设节点数量从3增加到了4,新的节点D经过哈希计算后映射到了下图中的位置:

可以看到key-01、key-03都不受影响,只有key-02需要被迁移节点D。

假设节点数量从3减少到了2,比如将节点A移除:

可以看到只有key-01需要被迁移节点B。

总结:因此在一致哈希算法中,如果增加或者移除一个节点,仅影响该节点在哈希环上顺时针相邻的后继节点,其它数据也不会受到影响。

使用一致性哈希算法有什么问题?

一致性哈希算法并不保证节点能够在哈希环上分布均匀,这样就会带来一个问题,会有大量的请求集中在一个节点上。

下图中3个节点的映射位置都在哈希环的右半边:

这时候有一半以上的数据的寻址都会找节点A,也就是访问请求主要集中的节点A上。在这种节点分布不均匀的情况下,进行容灾与扩容时,哈希环上的相邻节点容易受到过大影响,容易发生雪崩式的连锁反应。

上图中如果节点A被移除了,其上数据应该全部迁移到相邻的节点B上,会导致节点B的数据量、访问量都会迅速增加很多倍,一旦新增的压力超过了节点B的处理能力上限,就会导致节点B崩溃,进而形成雪崩式的连锁反应。

所以一致性哈希算法虽然减少了数据迁移量,但是存在节点分布不均匀的问题。

通过虚拟节点提高均衡度

要想解决节点能在哈希环上分配不均匀的问题,就是要有大量的节点,节点数越多,哈希环上的节点分布的就越均匀。这个时候我们可以加入虚拟节点,也就是对一个真实节点做多个副本。

具体做法:不再将真实节点映射到哈希环上,而是将虚拟节点映射到哈希环上,并将虚拟节点映射到实际节点,所以这里有「两层」映射关系。
比如对每个节点分别设置3个虚拟节点:

  • 对节点A加上编号来作为虚拟节点:A-01、A-02、A-03
  • 对节点B加上编号来作为虚拟节点:B-01、B-02、B-03
  • 对节点C加上编号来作为虚拟节点:C-01、C-02、C-03

    引入虚拟节点后,哈希环上变成有9个虚拟节点映射到哈希环上,哈希环上的节点数量多了3倍,节点在哈希环上的分布就相对均匀了。

当某个节点被移除时,对应该节点的多个虚拟节点均会移除,而这些虚拟节点按顺时针方向的下一个虚拟节点,可能会对应不同的真实节点,即这些不同的真实节点共同分担了节点变化导致的压力。因此虚拟节点除了会提高节点的均衡度,还会提高系统的稳定性。

有了虚拟节点后,还可以为硬件配置更好的节点增加权重(更多的虚拟机节点),所以带虚拟节点的一致性哈希方法不仅适合硬件配置不同的节点的场景,而且适合节点规模会发生变化的场景。

posted @ 2022-03-15 16:16  当康  阅读(894)  评论(0编辑  收藏  举报