githubEdit

3. 放置策略

放置策略会在多种场景下使用到:

  1. 执行shedding策略将bundle unload后,需要接着使用放置策略将该bundle分配给某个broker。

  2. 机器重启、broker缩容等场景下,某个broker服务的bundle全部unload下来,需要分配给集群里的其他broker。

  3. 集群初始化。

前面已经讲过,AvgShedder同时实现了卸载策略和放置策略,当一个 bundle 根据shedding策略执行unload操作时,其下一个 owner broker 便已依据shedding策略确定完毕,即第一种场景的逻辑我们设计好了。那么第二、第三种场景下,该如何分配这些bundle呢?

我们采用哈希分配的方式,即通过哈希映射将(bundle 名 + 随机数)映射到 broker。由于哈希映射大致符合均匀分布特性,所以 bundle 会大致均匀地分布于所有 broker 上。不过,鉴于不同 bundle 之间的流量存在差异,集群会出现一定程度的不均衡状况。但此问题并不严重,后续借助shedding策略便能实现均衡。况且像集群初始化、滚动重启、broker 缩容这类场景出现的频率较低,所以对整体影响不大。

另外读者可能会疑问:为何不直接将 bundle 名哈希映射到 broker,而是要额外添加一个随机数作为入参呢?

这是因为测试过程中发现了一个corner case:假假定 Pulsar 集群初始有 4 个节点,其 broker 列表为 [broker1, broker2, broker3, broker4] 。在集群达到稳定状态后,新增一个 broker5,随后关闭 broker3,此时 broker 列表会演变为以下几种情形:

  1. [broker1, broker2, broker5, broker4]

此时,broker5 恰好取代了 broker3 的位置。鉴于集群中 broker 的总数保持不变,broker3 所承载的大部分 bundles 经哈希算法计算后,所得 index 依旧为原值(即 2)。故而,broker3 上绝大部分的 bundles 将会转移至 broker5,而不是预期的均匀分布。由于 broker5 负载较低,这一异常情况所产生的影响较小。

如图所示,当关闭蓝色机器 broker3 后,可以观察到原本无负载的红色机器 broker5,几乎承接了 broker3 的全部负载。消息速率迅速攀升至与 broker3 关闭前相当的水平,其负载(CPU 使用率)也与其余三台 broker 近乎一致,而其余三台 broker 的负载则未见明显变化 。

  1. [broker1, broker2, broker4, broker5]

依据相同的算法逻辑,broker3 所承载的绝大部分 bundles 会转移至 broker4,这极有可能致使 broker4 过载,进而对性能产生影响。故而,为规避这种非均匀分布情形的出现,我们需引入一个随机数作为入参。

实现算法如下:

org.apache.pulsar.broker.loadbalance.impl.AvgShedder#getExpectedBroker

最新版代码只有随机数作为入参,去掉了bundle名称,因为发现去掉它也无影响。

Last updated

Was this helpful?