3. AvgShedder的诞生
面对Pulsar集群负载均衡效果不佳、稳定性差的问题,最开始我是打算基于现有的算法进行优化的,但是经过仔细的算法分析,我发现这不是简单的小修小补就能解决的,从而开始了新的负载均衡算法的设计。
AvgShedder算法几乎完美地解决了所提及的问题。自 2022 年起,便在生产环境中稳健运行。在 2024 年,我顺利推动该算法融入社区,并成功将其合并至社区主分支。如今,众多公司采用此算法,且都给予了积极反馈,这一点让我成就感满满。
具体的算法原理会在后面章节中详细介绍,这里我们展示一下它的效果,还是根据适应性、稳定性、正确性等维度对它进行评分,我们得到下面表格:
策略
适应异构环境
(适应性)
适应负载抖动
(稳定性)
过度加载问题
(正确性)
过度卸载问题
(正确性)
负载均衡速度
ThresholdShedder + LeastResourceUsageWithWeight
一般
良
差
差
一般
UniformLoadShedder +
LeastLongTermMessageRate
差
差
良
良
一般
AvgShedder
一般
良
良
良
良
注记:AvgShedder同时实现了卸载策略LoadSheddingStrategy和放置策略ModularLoadManagerStrategy,因此我们不需要(也不能)将其与其他算法进行组合搭配,使用时需要同时配置
loadBalancerLoadSheddingStrategy=org.apache.pulsar.broker.loadbalance.impl.AvgShedder
loadBalancerLoadPlacementStrategy=org.apache.pulsar.broker.loadbalance.impl.AvgShedder 可以看到,AvgShedder在各个方面都达到良好的水平,是一个没有明显短板的负载均衡算法。在实际应用中也印证了这一点:

集群里资源使用率的极差(最高与最低资源使用率的差距)保持在15%以内,因为我们使用默认配置loadBalancerAvgShedderLowThreshold=15,它控制了触发负载均衡算法的资源使用率的极差阈值。
注记:我们机器的瓶颈是CPU使用率,因此对CPU使用率极差设置了监控图。
如果你希望集群里的负载更加均衡,可以进一步将其降低为loadBalancerAvgShedderLowThreshold=10,那么就能保证集群资源使用率的极差不超过10%。但是这是有代价的,触发的门槛越低,那么就会越容易触发,从而牺牲集群流量稳定性。
我们有一个机制来增强稳定性,默认配置loadBalancerAvgShedderHitCountLowThreshold = 8决定了阈值需要连续触发8次才会真正执行算法,因此短暂的流量波动不会错误触发算法的执行。这个值越高,那么流量的稳定性越高,当然这也是有代价的,这个值越高,那么要触发负载均衡所需的时间越长。结合前面介绍的配置loadBalancerSheddingIntervalMinutes=1,每1min执行一次负载均衡判断,因此默认情况下要持续8min的不均衡才会真正触发负载均衡。
在集群滚动重启、broker扩容等情况下,往往会出现不同broker之间负载差距较大的情况,而我们又希望较为快速地完成负载均衡,就会跟上面所说的时间代价产生冲突。鉴于此,我们进一步引入一种机制:当资源使用率极差超过 40% 时,仅需连续 2 次触发,即可真正启动负载均衡算法的执行。如此一来,便能完美解决触发迟缓的问题。
AvgShedder 通过高低两种阈值的方式,在稳定性和及时性之间达到了良好的平衡。对于较低的触发阈值,借助较高的触发次数要求来提高稳定性;对于较高的触发阈值,则借助较低的触发次数要求来提高及时性。生产环境的效果如下图所示:

在采用旧负载均衡算法期间,我们的 Pulsar 集群每日会引发几十乃至上百次的负载切换。尤其在流量高峰期,频繁出现误触发负载切换的情况,致使用户流量被切断,进而招致用户的负面反馈。而在引入 AvgShedder 之后,负载切换的触发次数显著降低至月均一两次,这一方案极为有效地解决了流量稳定性问题,用户投诉的现象也随之彻底消失。
Last updated
Was this helpful?

