githubEdit

1. LeastLongTermMessageRate

1.1 打分算法

LeastLongTermMessageRate 策略最初设计用于配合 OverloadShedder 使用。在计算 Broker 的负载分数 scores 时,该策略未考虑权值配置(例如 loadBalancerCPUResourceWeight),而是直接采用 CPU、直接内存及网络的最大资源使用率,以此作为 Broker 的初步分数。此外,它复用了 OverloadShedder 的配置 loadBalancerBrokerOverloadedThresholdPercentage。若初步分数高于该配置的默认值 85%,则将 score 设为 INF(即无穷大);反之,则依据消息速率计算 Broker 的最终分数。

最后,从最终分数最小的 Broker 中随机选取一个返回。若每个 Broker 的分数均为 INF,则随机挑选一个 Broker 返回。

注意:由于分数是double类型,几乎不可能有多个broker具有同样的分数,因此可以认为:每次都选择最终分数最小的某个broker返回,作为bundle的新owner。

实际上,LeastLongTermMessageRate 打分算法的本质是依据消息速率进行打分。尽管初步分数基于最大资源使用率得出,但其目的是初步筛除超载的 broker,这些超载的 broker 不会作为候选 broker 被返回(除非所有 broker 均处于超载状态)。最终,根据消息速率的大小计算出最终分数,并依据该最终分数对 broker 进行排序。

既然LeastLongTermMessageRate的打分是根据消息速率来执行的,那么它跟UniformLoadShedder一样,也会面临异构环境的问题(适应性问题)。

注记:回顾第一章的定义,适应性问题是指旧算法无法适应异构环境,相比低性能机器,更高性能的机器无法承担更多的流量负载。

1.2 过度加载

那么,为解决异构环境的问题,能否将 LeastLongTermMessageRate 打分算法调整为依据资源使用率来打分呢?

答案是否定的。在详细解答该问题之前,先来介绍过度加载问题(第一章介绍过)。

举个例子,假如当前存在11个broker,资源使用率均为50%左右,阈值设置为70%,由于集群压力不大尝试缩容3个broker,那么这三个broker上面的bundle会全部卸载下来,然后开始加载到其余broker上。因为负载数据是定期更新的,远远赶不上topic lookup、bundle load的速度(而且由于Zookeeper的性能限制,也注定无法加快),因此leader broker内存中每个broker的负载数据可以认为是短期内无更新的,那么这段时间内最低分的broker都会是同一个broker,因此bundle会全部加载到该低载broker上,导致该低载broker变成高载,即过度加载。

这里LeastLongTermMessageRate使用了PreallocatedBundleData里的数据解决了这个问题。

org.apache.pulsar.broker.loadbalance.impl.LeastLongTermMessageRate#getScore

在对broker计算最终得分时,不仅会使用broker自身聚合得到的长期消息速率,还会加上已经分配给该broker但是还没统计进broker负载数据的bundle的消息速率。最终得分的计算公式为:该broker的长期聚合得到的消息进出速率之和,加上预分配bundle的消息进出速率之和。即

举个例子,现在有两个bundle均为20KB/s,broker1、broker2分别为100KB/s、110KB/s,则分配第一个bundle的时候分配给了broker1,但是broker1的负载数据短期内还不会更新,接下来要分配第二个bundle,此时虽然broker1的负载数据还没变化,但是它的打分已经变成了100+20=120KB/s,因此这次分配bundle给broker2,这就避免了过度加载问题。

因此现在可以回答前面提出的问题:不可以改成根据资源使用率来打分,因为bundle只有消息速率、流量吞吐的统计数据,无法预测加载一个bundle会使某个broker增加多少资源使用率,因此也会无法使用PreallocatedBundleData的数据来预估。

注记:过度加载问题正是后面的算法LeastResourceUsageWithWeight所要面对的,因为它是根据资源使用率来打分的。

1.3 算法组合

下面我们尝试结合LoadSheddingStrategy策略来一起分析效果。首先是

  • LeastLongTermMessageRate + OverloadShedder

这是最开始的一个组合,但是由于OverloadShedder固有的一些缺陷,不推荐

  • LeastLongTermMessageRate + ThresholdShedder

这个组合比LeastLongTermMessageRate+OverloadShedder还要更糟糕一点,不推荐

因为ThresholdShedder给broker打分是根据资源使用率来计算的,而LeastLongTermMessageRate是根据消息速率来打分的,这种卸载和放置的标准不一致很有可能导致反复的负载均衡执行,卸载出来bundle后却放到了错误的brokerX上,导致下一次执行shedding时又判定brokerX为超载。这也是后面提出新放置策略LeastResourceUsageWithWeight的动机。

  • LeastLongTermMessageRate + UniformLoadShedder

这是一个比较合适的组合,推荐

它成功地避免了过度加载问题,卸载和放置策略的打分算法都是以消息速率为标准,但是以消息速率为标准自然就会面临异构环境的问题(适应性问题)。而且UniformLoadShedder无法应对短期的流量波动,稳定性欠缺

Last updated

Was this helpful?