一致性哈希(复习版)

转载请标明原创:https://blog.csdn.net/weixin_41896463/article/details/106304145

传统经典的分布式集群处理

服务器是一个集群,前端保留了某个固定的hash函数,每次都通过某个请求字段来hash后取模,判断需要到服务器集群中的哪台机器上处理。这样子,可以实现集群的负载均衡(因为hash函数得到的情况是均匀分布的)。

但是当我要新增机器或者删除机器时,就需要重新计算哈希。(比如从3台增加到5台机器,前端的哈希取模就需要修改为5,同时原本3台机器中保存的数据,需要全部重新计算后分配,数据迁移量巨大。)

一致性哈希就可以极大降低数据迁移量,同时也能够保证负载均衡。

 

一致性哈希

一致性哈希,同样需要hash空间,且一般为2^32,将hash空间想象成首尾相连的一个环,称为哈希环。(自己脑补吧,不画了)

然后将节点(服务器)进行哈希,按照一定的规则,比如按照 IP 地址的哈希值,让节点落在哈希环上。

同时我们的请求数据,同样也需要根据一定的规则进行哈希,同样也会落到这个环上。则约定:

  • 如果请求刚好落在节点上,则由此节点处理
  • 如果没有,则顺时针方向寻找,交给第一个遇到的节点处理

 

这时候,

  • 如果新增一个节点m4,只需要顺时针找到它的下一个节点m3,将m3中部分需要交给m4的数据迁移到m4上(简单通过边界划分就可以获取到需要迁移的数据)即可,其他节点的数据,以及m3中不是交给m4处理的其他数据,都不需要进行迁移
  • 如果删除一个节点m3,只需要将m3所有数据迁移到它顺时针寻找到的第一个节点即可。

可以看出,如果使用上面的一致性哈希,可以大大降低数据的迁移量!

 

但是:上面的结构能够解决数据迁移量问题,还是存在一个很严重的问题:数据不均衡。我们直到hash函数只有在很大样本量计算的时候,数据才能说是相对平均分布,但数据量小的时候(比如只有3台机器),想要它刚好均分一整个哈希环,很难。即使你很牛逼,设计了一个hash算法能够均衡分割哈希环。当新增或删除一个节点时,同样是废了,迁移后数据同样不均衡(即出现数据倾斜问题)。

怎么解决上面的这种不均衡问题?引入虚拟节点,就可以解决!

 

虚拟节点

为每台物理的机器新增许多个虚拟节点,虚拟节点进行了哈希后分布到哈希环上(物理节点就不存了)

比如机器m1,拥有1000个虚拟节点m1-1、m1-2、m1-3  ……

为什么说是虚拟的呢?因为这些虚拟节点都不实际存放数据,而是只要是按照上面顺时针的要求,匹配到m1的虚拟节点上的数据,全部都存入到物理机器m1上。(这就需要前端保存物理节点和虚拟节点之间的映射关系:路由表)

 

简单的说,就是物理节点被多个虚拟节点代替了,虚拟节点在哈希环上的操作和数据的匹配,都和原本一样,无论找到的是哪个虚拟节点,只要是同一个物理节点拥有的,就将数据/请求发送到相应的物理节点上进行处理和保存。

 

为什么使用虚拟节点就可以解决数据倾斜问题?

我们上面提到hash函数在数据量大的时候才会显示均分的特性,所以使用大量的虚拟节点,可以将哈希环进行相对平均的划分。

在新增/删除一个节点时,就在哈希环上新增/删除相应的众多虚拟节点,同样也是均衡的。

而由于引入了虚拟节点,数据迁移的判断,就比较多了(需要众多的虚拟节点)。迁移的这些数据,不再是简单从一个物理机器上进行迁移,而是几乎平分到所有的物理机器上,即几乎所有的物理机器都有需要迁移的数据,但是数据的迁移量总和还是保持和原来一样的极低迁移量

 

一致性哈希应用案例

常用在服务器的设计上,有集群、负载均衡要求的,一般都需要一致性哈希或者使用其思想改造。

比如 Dubbo 的负载均衡。

而Redis 集群中的哈希槽(16384个),虽然不是使用一致性哈希,不过也有一致性哈希的影子。(Redis 没有直接使用哈希算法 hash(),而是使用了crc16校验算法。)

哈希槽和哈希环本质一样,只不过哈希槽并不需要处理哈希环会出现的数据倾斜问题,哈希槽是自定义分配的,哪个机器牛逼,就分多点槽给它处理,是根据机器配置情况决定的,不是严格意义上的平均。这里不做重点讨论。

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值