我在Dubbo源码里学到了如何保证虚拟节点均匀分布!

本文探讨了在一致性哈希算法中,虚拟节点如何保证分布均匀的问题。通过分析Dubbo源码中的实现,揭示了通过MD5散列和特定的定位算法,如何利用散列函数的特性确保映射分布的均匀性,从而实现虚拟节点在hash环上的相对均匀分布。同时,强调了深入理解算法细节的重要性。
摘要由CSDN通过智能技术生成

上周更新了一篇文章《一致性Hash算法与虚拟节点》,阅读和收藏人数挺多的。

今天有朋友问了我一个问题,虚拟节点如何保证均匀分布?
插图1
我不假思索的回答,

不需要保证虚拟节点的均匀分布,

虚拟节点用以保证相对的均匀靠得是量变产生质变,

就像我文末提到的,在实际场景中,虚拟节点的个数只有3个是远远不够的。

例如Dubbo中用到一致性hash算法时,默认的虚拟节点个数是160个,

假设我们有四个服务节点需要创建虚拟节点,那就会有 4 * 160 = 640 个虚拟节点,

在这样大量的基数下,必然他们的分布就会呈一种相对均匀的状态。
插图2
回答完我感觉很满意,不愧是我!

可转念一想,再想,三想,

好像不是这么一回事,

别说是有640个节点了,就算有6400个,64000个节点又如何呢?

在极小极小的概率下,如果hash算法不能保证映射的均匀性,

他们依然可能落在十分聚集的一小块区域中。

反推一下,既然一致性hash算法作为一个成熟并拥有很多应用场景的算法,

不可能如此不严谨,所以hash算法本身应该是可以保证映射的一致性的。

“应该”?这么不确定可不行,我得好好补补空白,确实之前没有去了解过hash算法到底实现了个啥。
插图3
东查西查,终于有了答案。

百度百科对Hash的名次解释如下:

Hash,一般翻译做散列、杂凑,或音译为哈希,是把任意长度的输入(又叫做预映射pre-image)通过散列算法变换成固定长度的输出,该输出就是散列值。

哦,原来就是散列函数啊!

那就简单了,散列函数我本科学过啊!

脑海一番搜索,糟糕,我真的学过吗?唯一的印象就是学过。
插图4
没事,学过忘了没关系,再学就完事了。

以下是干货,

一个合格的散列函数包含三个特征:

  • 单向性:容易计算输入的散列结果,但是从散列结果无法倒推出输入;
  • 抗冲突性:很难找到两个不同的输入散列结果相同;
  • 映射分布均匀性和差分分布均匀性:散列结果中 bit 位上的 0 和 1 的数量应当大致相等;改变输入内容的 1 个 bit 信息会导致散列结果一半以上的 bit 位变化(雪崩效应)。

真刺激,到这是不是就完事了,散列函数保证了映射的分布均匀性。

我劝你要不要再回去看两遍映射分布均匀性和差分分布均匀性的内容。
插图
看完了吗?

再想想《一致性Hash算法与虚拟节点》中的hash环,

有没有顿时反应过来,这边又TM不严谨了。

img

说好的散列结果中bit位上 0 和 1 的数量大致相等,这要是映射到hash环上,

最小值岂不是 00000000000000001111111111111111,

最大值岂不是 11111111111111110000000000000000,

(别数数字,我随便打的,你懂我意思吧)

那在hash环上不就出现了一段真空地带了吗?
插图6
虽然实际上真空地带比图上的还小,只有 65536/4294967295 约等于 百万分之十五,

但这微小的缺口无疑将带来无法估计的灾难,尤其是在实际生产环境中,

你永远不知道一个微小的漏洞可能会造成多大的后果。

评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Kareza

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值