Rebalance机制


当消费者启动之后,kafka会为消费者分配分区进行消费。当消费者和分区的关系发生了变化之后,就会重新分配分区给消费者,例如:

  • 某个消费者挂了
  • 来了个新的消费者
  • 主题增加了分区

重新分配分区这个动作就叫做Rebalance。

Rebalance过程

假设现在有3个分区,2个消费者c1和c2,然后新来了一个消费者c3,触发了Rebalance,整个过程如下:

  1. broker中的组协调者(Group Coordinator)收到c3的Join Group请求,知道有新消费者来了
  2. 组协调者在心跳中告知c1和c2
  3. c1和c2放弃已持有的分区,此时c1和c2也相当于一个新的消费者,给组协调者发送Join Group请求
  4. 组协调者按定好分配方案,将分配方案发给每个消费者
  5. 3个消费者开始消费

分配策略

分配分区有几种策略,可以使用partition.assignment.strategy进行配置,默认值为:

org.apache.kafka.clients.consumer.RangeAssignor,org.apache.kafka.clients.consumer.CooperativeStickyAssignor

range策略

partition.assignment.strategy设置为org.apache.kafka.clients.consumer.RangeAssignor

这种策略下,分配方式是在平均分的基础上,多出来的先给排在前面的消费者,举几个例子:

  • 假设3个分区,3个消费者,则是每个消费者分配1个分区

  • 假设4个分区,3个消费者,则是0,1分区给第一个消费,2,3分区分别给其他2个消费者

轮训策略

partition.assignment.strategy设置为org.apache.kafka.clients.consumer.RoundRobinAssignor

这种策略下,分区会按顺序依次分配给消费者,例如有10个分区,3个消费者:

  1. 0分区给消费者0
  2. 1分区给消费者1
  3. 2分区给消费者2
  4. 3分区给消费者0
  5. 4分区给消费者1
  6. 依次类推

sticky策略

partition.assignment.strategy设置为org.apache.kafka.clients.consumer.StickyAssignor

这是带有粘性的策略,它会在发生Rebalance时:

  • 尽可能保持原来的分配关系
  • 尽可能均匀的分配分区。

Cooperative Sticky策略

partition.assignment.strategy设置为org.apache.kafka.clients.consumer.CooperativeStickyAssignor

这是2.4版本新增的策略,原有的sticky策略虽然可以尽量保证原有的分配分案,但是每一个消费者仍然需要先释放已持有的分区资源。

于是就有新Cooperative Sticky策略,这个策略相比于旧的策略有什么优势呢?为此,我们需要先了解旧的策略有什么劣势。

在旧策略中,当发生再平衡时,会发生STW(Stop The Word):所有的消费者需要先放弃当前已经持有的分区资源,等待重新分配。

也就是说在这段时间内,主题资源处于不可用状态,直到rebalance结束,才会重新开始消费。

如果是大规模集群,这种大规模的STW是一种灾难。

而新的Cooperative Sticky策略,将原来的一次大规模rebalance操作,拆分成了多次小规模的rebalance,直至最终平衡完成。

仍然假设现在有3个分区,2个消费者c1和c2,c1消费分区0和1,c2消费分区2。

然后新来了一个消费者c3,触发了Rebalance,具体步骤如下:

  1. 新消费者来时,组协调者通知消费者,和旧策略不同,c1,c2发送Join Group给组协调者时,不必放弃已持有的分区,并将当前持有的分区信息告知组协调者
  2. 组协调者综合现在所有的情况,通知c1放弃分区1,此时算一次小规模rebalance完成。
  3. 接着继续rebalance,将暂时无人消费的分区1分配给新来的c2即可,rebalance全部完成。
文章作者: 周君
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 周君 !
评论