什么意思呢?我用大白话加画图的方式给你简单的介绍一下 。
一致性哈希,你可以想象成一个哈希环,它由0到2^32-1个点组成 。A,B,C分别是三台服务器,每一台的IP加端口经过哈希计算后的值,在哈希环上对应如下:

文章插图
当请求到来时,对请求中的某些参数进行哈希计算后,也会得出一个哈希值,此值在哈希环上也会有对应的位置,这个请求会沿着顺时针的方向,寻找最近的服务器来处理它,如下图所示:

文章插图
一致性哈希就是这么个东西 。那它是怎么解决服务器的扩容或收缩导致大量的数据迁移的呢?
看一下当我们使用一致性哈希算法时,加入服务器会发什么事情 。
当我们加入一个D服务器后,假设其IP加端口,经过哈希计算后落在了哈希环上图中所示的位置 。

文章插图
这时影响的范围只有图中标注了五角星的区间 。这个区间的请求从原来的由C服务器处理变成了由D服务器请求 。而D到C,C到A,A到B这个区间的请求没有影响,加入D节点后,A、B服务器是无感知的 。
所以,在一致性哈希算法中,如果增加一台服务器,则受影响的区间仅仅是新服务器(D)在哈希环空间中,逆时针方向遇到的第一台服务器(B)之间的区间,其它区间(D到C,C到A,A到B)不会受到影响 。
在加入了D服务器的情况下,我们再假设一段时间后,C服务器宕机了:

文章插图
当C服务器宕机后,影响的范围也是图中标注了五角星的区间 。C节点宕机后,B、D服务器是无感知的 。
所以,在一致性哈希算法中,如果宕机一台服务器,则受影响的区间仅仅是宕机服务器(C)在哈希环空间中,逆时针方向遇到的第一台服务器(D)之间的区间,其它区间(C到A,A到B,B到D)不会受到影响 。
综上所述,在一致性哈希算法中,不管是增加节点,还是宕机节点,受影响的区间仅仅是增加或者宕机服务器在哈希环空间中,逆时针方向遇到的第一台服务器之间的区间,其它区间不会受到影响 。
是不是很完美?不是的,理想和现实的差距是巨大的 。
一致性哈希算法带来了什么问题?

文章插图
当节点很少的时候可能会出现这样的分布情况,A服务会承担大部分请求 。这种情况就叫做数据倾斜 。
怎么解决数据倾斜呢?加入虚拟节点 。
怎么去理解这个虚拟节点呢?
首先一个服务器根据需要可以有多个虚拟节点 。假设一台服务器有n个虚拟节点 。那么哈希计算时,可以使用IP+端口+编号的形式进行哈希值计算 。其中的编号就是0到n的数字 。由于IP+端口是一样的,所以这n个节点都是指向的同一台机器 。
如下图所示:

文章插图
在没有加入虚拟节点之前,A服务器承担了绝大多数的请求 。但是假设每个服务器有一个虚拟节点(A-1,B-1,C-1),经过哈希计算后落在了如上图所示的位置 。那么A服务器的承担的请求就在一定程度上(图中标注了五角星的部分)分摊给了B-1、C-1虚拟节点,实际上就是分摊给了B、C服务器 。
一致性哈希算法中,加入虚拟节点,可以解决数据倾斜问题 。
当你在面试的过程中,如果听到了类似于数据倾斜的字眼 。那大概率是在问你一致性哈希算法和虚拟节点 。
在介绍了相关背景后,我们可以去看看一致性哈希算法在Dubbo中的应用了 。
一致性哈希算法在Dubbo中的应用前面我们说了Dubbo中负载均衡的实现是通过
org.apache.dubbo.rpc.cluster.loadbalance.AbstractLoadBalance中的 doSelect 抽象方法实现的,一致性哈希负载均衡的实现类如下所示:
org.apache.dubbo.rpc.cluster.loadbalance.ConsistentHashLoadBalance

文章插图
由于一致性哈希实现类看起来稍微有点抽象,不太好演示,所以我想到了一个"骚"操作 。前面的文章说过 LoadBalance 是一个 SPI 接口:

推荐阅读
- 带你走进潮汕工夫茶,工夫茶点心
- 带你了解安徽四大名茶,安徽茶打四大品牌
- 带你去看美团架构
- 万字长文讲解编码知识,看这文就够了!| 原力计划
- 一文带你彻底理解Linux的各种终端类型及概念
- 一篇长文学懂入门推荐算法库:surprise
- 电力负荷怎么计算?几分钟带你了解清楚,好东西,赶紧收藏
- 最新百度信息流产品手册,带你全面了解百度产品
- 三分钟带你了解香槟产区另一面,谈香槟,你也是行家
- 没有人比我更懂电流,今天带你重新认识电流
