2万字长文带你细细盘点五种负载均衡策略( 七 )


2万字长文带你细细盘点五种负载均衡策略

文章插图
 
Dubbo2.6.0最小活跃数算法Bug二
这个Bug我没有遇到,但是我在官方文档上看了其描述(官方文档中的版本是2.6.4),引用如下:
2万字长文带你细细盘点五种负载均衡策略

文章插图
 
官网上说这个问题在2.6.5版本进行修复 。我对比了2.6.0/2.6.5/2.7.4.1三个版本,发现每个版本都略有不同 。如下所示:
2万字长文带你细细盘点五种负载均衡策略

文章插图
 
图中标记为①的三处代码:
2.6.0版本的是有Bug的代码,原因在上面说过了 。
2.6.5版本的修复方式是获取随机数的时候加一,所以取值范围就从**[0,totalWeight)变成了[0,totalWeight]**,这样就可以避免这个问题 。
2.7.4.1版本的取值范围还是[0,totalWeight),但是它的修复方法体现在了标记为②的代码处 。2.6.0/2.6.5版本标记为②的地方都是if(offsetWeight<=0),而2.7.4.1版本变成了if(offsetWeight<0) 。
你品一品,是不是效果是一样的,但是更加优雅了 。
朋友们,魔鬼,都在细节里啊!
好了,进入下一议题 。
一致性哈希负载均衡这一部分是对于Dubbo负载均衡策略之一的一致性哈希负载均衡的详细分析 。对源码逐行解读、根据实际运行结果,配以丰富的图片,可能是东半球讲一致性哈希算法在Dubbo中的实现最详细的文章了 。
本小节所示源码,没有特别标注的地方,均为2.7.4.1版本 。
在撰写本文的过程中,发现了Dubbo2.7.0版本之后的一个bug 。会导致性能问题,如果你们的负载均衡配置的是一致性哈希或者考虑使用一致性哈希的话,可以了解一下 。
哈希算法在介绍一致性哈希算法之前,我们看看哈希算法,以及它解决了什么问题,带来了什么问题 。
2万字长文带你细细盘点五种负载均衡策略

文章插图
 
如上图所示,假设0,1,2号服务器都存储的有用户信息,那么当我们需要获取某用户信息时,因为我们不知道该用户信息存放在哪一台服务器中,所以需要分别查询0,1,2号服务器 。这样获取数据的效率是极低的 。
对于这样的场景,我们可以引入哈希算法 。
2万字长文带你细细盘点五种负载均衡策略

文章插图
 
还是上面的场景,但前提是每一台服务器存放用户信息时是根据某一种哈希算法存放的 。所以取用户信息的时候,也按照同样的哈希算法取即可 。
假设我们要查询用户号为100的用户信息,经过某个哈希算法,比如这里的userId mod n,即100 mod 3结果为1 。所以用户号100的这个请求最终会被1号服务器接收并处理 。
这样就解决了无效查询的问题 。
但是这样的方案会带来什么问题呢?
扩容或者缩容时,会导致大量的数据迁移 。最少也会影响百分之50的数据 。
2万字长文带你细细盘点五种负载均衡策略

文章插图
 
为了说明问题,我们加入一台服务器3 。服务器的数量n就从3变成了4 。还是查询用户号为100的用户信息时,100 mod 4结果为0 。这时,请求就被0号服务器接收了 。
当服务器数量为3时,用户号为100的请求会被1号服务器处理 。
当服务器数量为4时,用户号为100的请求会被0号服务器处理 。
所以,当服务器数量增加或者减少时,一定会涉及到大量数据迁移的问题 。可谓是牵一发而动全身 。
对于上诉哈希算法其优点是简单易用,大多数分库分表规则就采取的这种方式 。一般是提前根据数据量,预先估算好分区数 。
其缺点是由于扩容或收缩节点导致节点数量变化时,节点的映射关系需要重新计算,会导致数据进行迁移 。所以扩容时通常采用翻倍扩容,避免数据映射全部被打乱,导致全量迁移的情况,这样只会发生50%的数据迁移 。
假设这是一个缓存服务,数据的迁移会导致在迁移的时间段内,有缓存是失效的 。
缓存失效,可怕啊 。还记得我之前的文章吗,《当周杰伦把QQ音乐干翻的时候,作为程序猿我看到了什么?》就是讲缓存击穿、缓存穿透、缓存雪崩的场景和对应的解决方案 。
一致性哈希算法为了解决哈希算法带来的数据迁移问题,一致性哈希算法应运而生 。
对于一致性哈希算法,官方说法如下:
一致性哈希算法在1997年由麻省理工学院提出,是一种特殊的哈希算法,在移除或者添加一个服务器时,能够尽可能小地改变已存在的服务请求与处理请求服务器之间的映射关系 。一致性哈希解决了简单哈希算法在分布式哈希表( Distributed Hash Table,DHT) 中存在的动态伸缩等问题 。


推荐阅读