如何平滑加权轮询负载均衡的底层逻辑以适应需求?
摘要:你好呀,我是歪歪。 五年前,我写了一篇关于平滑加权轮询负载均衡策略的算法。 那是我第一次接触到平滑加权轮询负载均衡策略,最后结果呈现出“平滑”的轮询效果之后,我感觉非常厉害。 但是,在当年的文章中有这样的一句话: 我想了很久,我还是不知道背
你好呀,我是歪歪。
五年前,我写了一篇关于平滑加权轮询负载均衡策略的算法。
那是我第一次接触到平滑加权轮询负载均衡策略,最后结果呈现出“平滑”的轮询效果之后,我感觉非常厉害。
但是,在当年的文章中有这样的一句话:
我想了很久,我还是不知道背后的数学原理是什么。
由于印象过于深刻,所以五年过去了,关于这个问题,不能说日思夜想吧,但也是念念不忘。
最近一次这个问题再次浮现在脑海中的时候,我决定再次对这个问题发起冲锋。
在参考资料以及 DeepSeek 的加持下,这次终于算是“知其然,也知其所以然”了。
不平滑的加权轮询
在说平滑的加权轮询之前,我们还是得用两三句话简单铺垫一下啥是不平衡的加权轮询,方便后面对比。
举个例子。
假设 A,B,C 三台服务器的权重分别为 5:1:1。
如果是不平滑的加权轮询,最终的执行顺序会是这样的:
会连续选择出权重高的节点,主打一个忙的忙死,闲的闲死。
这样就显得不平滑。
平滑的加权轮询
如果是平滑的加权轮询,它的处理请求的过程是这样的:
假设每个节点有两个权重:
一个是配置的 weight,不会变化。一个是 currentWeight 会动态调整,初始值为 0。
每次请求进来,选择节点的时候,按照以下三步执行:
遍历节点列表,让每个节点的 currentWeight 都加上自身权重。然后所有节点中,谁的 currentWeight 最大,谁就会被选中。被选中后,将选中节点的 currentWeight 减去权重总和。
上面的逻辑非常简单。
接下来我就配合大量的图片,带着你一步步的推演一下这个过程。
还是以 A:B:C=5:1:1 为例。
我们回到这句话中:
假设每个节点有两个权重:
*一个是配置的weight,不会变化。
*一个是currentWeight会动态调整,初始值为0。
那么最开始,这三个节点,每个节点:
配置的 weight 为 A:B:C=5:1:1。currentWeight 为 A:B:C=0:0:0。
第一次请求
第一次请求进来了,第一步会干啥?
遍历节点列表,让每个节点的 currentWeight 都加上自身权重。
所以,此时 currentWeight 从 A:B:C=0:0:0 变成 A:B:C=5:1:1。
紧接着干啥?
然后所有节点中,谁的 currentWeight 最大,谁就会被选中。
那肯定是 A 的 currentWeight 最大,因为它是 5,另外两个都是 1。
所以,第一次请求,会让 A 节点来处理。
但是,别忘了,还有关键的一步:
被选中后,将选中节点的 currentWeight 减去权重总和。
由于 A 被选中了,所以它的 currentWeight= 5-7=-2。
其中的 7 是 A、B、C 的总权重。
所以,第一次请求过后。
每个节点的 currentWeight 为 A:B:C=-2:1:1。
按照上面的描述,我们画个步骤图:
如果只看最后结果,就是这样的:
第二次请求
第一次请求结束后,调整之后的 currentWeight 是 A:B:C=-2:1:1。
现在第二次请求进来了,第一步会干啥?
遍历节点列表,让每个节点的 currentWeight 都加上自身权重。
所以:
A 的 currentWeight=-2+5=3B 的 currentWeight=1+1=2C 的 currentWeight=1+1=2
还是 A 的 currentWeight 权重最高,第二次还是 A 来处理这个请求。
由于 A 被选中了,所以它的 currentWeight= 3-7=-4。
此时,每个节点的 currentWeight 为 A:B:C=-4:2:2。
按照上面的描述,我们再画个步骤图:
因此,第二次请求完成之后,整个结果图是这样的:
后面的内容哪怕你跳着看都行,但是在这一步,
你必须要明白第二次请求的这两组数字是怎么来的:
A:B:C=3:2:2A:B:C=-4:2:2
第二次请求搞明白了,后面的请求就是依葫芦画瓢了。
第三次请求
第二次请求结束后,调整之后的 currentWeight 是 A:B:C=-4:2:2。
现在第三次请求进来了,第一步会干啥?
老规矩:
遍历节点列表,让每个节点的 currentWeight 都加上自身权重。
所以:
A 的 currentWeight=-4+5=1B 的 currentWeight=2+1=3C 的 currentWeight=2+1=3
这个时候,B、C 的权重都是 3,都最高,怎么办?
按照顺序来,就行。
选择 B。
