什么是Kafka的重平衡机制?


一、什么是Kafka的重平衡机制?

Kafka的重平衡(Rebalance)机制指的是消费者组(Consumer Group)新增或删除消费者(Consumer)时,Kafka集群会重新分配topic分区给各个消费者,以保证每个消费者消费的分区数量尽可能平衡。

二、什么时候触发重平衡?

重平衡有3个触发条件:

  • 消费祖成员数量发生变化(consumer group)
  • 订阅主题数量发生变化(topic)
  • 订阅主题的分区数发生变化(partition)

三、重平衡策略有哪些?

Kafka提供了三种重平衡策略,分别为Range、RoundRobin和Sticky。

1、Range

Range是基于每个topic的partition分配,如果topic的partition不能平均分配给组内每个consumer,那么该topic下某些消费者会被分配到额外的分区。

举个例子,给定下列条件:

  • 两个消费者:C1和C2
  • 两个主题:t1和t2
  • 每个主题三个分区:t1p1、t1p2、t1p3、t2p1、t2p2、t2p3

那么分配情况可能会是:

  • C1:t1p1、t1p3、t2p1、t2p3
  • C2:t1p2、t2p2

解释如下:

  • 每个主题三个分区分配给两个消费者,意味着有一个消费者会分到一个分区,另外一个消费者会分到两个分区
  • 如果两个主题三个分区都是把多的分区分给同一个消费者,就会出现分区不平衡的情况(一个分到四个分区,一个分到两个分区)

2、RoundRobin(默认)

RoundRobin是基于全部topic的partition分配,是Kafka默认的重平衡策略。

举个例子,给定下列条件:

  • 两个消费者:C1和C2
  • 两个主题:t1和t2
  • 每个主题三个分区:t1p1、t1p2、t1p3、t2p0、t2p1、t2p2

那么分配情况可能是:

  • C1:t1p1、t1p2、t2p3
  • C2:t1p3、t2p1、t2p2

解释如下:

  • 每个主题三个分区分配给两个消费者,意味着有一个消费者会分到一个分区,另外一个消费者会分到两个分区
  • 由于RoundRobin策略,会将多次分配尽可能平衡,使每个消费者获得的分区数尽可能相同

但这只是存在两个主题三个分区且能刚好分配相同的情况下,在一些场景下也是会出现分区不平衡的情况,举例如下:

  • 三个消费者:C1、C2、C3
  • 三个主题:t1、t2、t3
  • 分别对应1、2、3个分区:t1p1、t2p1、t2p2、t3p1、t3p2、t3p3
  • 订阅情况:C1订阅t1,C2订阅t1、t2,C3订阅t1、t2、t3

那么分配情况可能是:

  • C1:t1p1
  • C2:t2p1
  • C3: t2p2、t3p1、t3p2、t3p3

解释如下:

  • 在没t3之前,t1和t2是可以平均分配给三个消费者的,但是t3只有C3订阅了,导致C3分配到了三个分区,所以导致分区不平衡

3、Sticky

Sticky是最新也是最复杂的策略,主要是为了让目前的分配尽可能保持不变,只挪动尽可能少的分区来实现重平衡。

举个例子,给定下列条件:

  • 三个消费者:C1、C2、C3
  • 四个主题:t1、t2、t3、t4
  • 每个主题两个分区:t1p1、t1p2、t2p1、t2p2、t3p1、t3p2、t4p1、t4p2

那么分配情况可能是:

  • C1:t1p1、t2p2、t4p1
  • C2:t1p2、t3p1、t4p2
  • C3:t2p1、t3p2

假设这时候C2挂掉了,如果是RoundRobin策略,那么分配情况会变为:

  • C1:t1p1、t2p1、t3p1、t4p1
  • C3:t1p2、t2p2、t3p2、t4p2

如果说他会全部打乱再分配,而如果是Sticky策略,那么分配情况会变为:

  • C1:t1p1、t2p2、t4p1、t3p1
  • C3:t2p1、t3p2、t1p2、t4p2

也就是说,尽可能保留了原来的分区情况,在原先的基础上去做平均分配,不过这个策略目前使用不多。

四、如何避免重平衡?

避免重平衡,就要避免消费者消费出现问题,可以从以下几个参数来调整:

  • session.timeout.ms:心跳超时时间,默认10s
  • heartbeat.interval.ms:心跳请求频率,默认3s。频率越高越不容易出现重平衡,但是会影响性能
  • max.poll.interval.ms:调用poll方法间隔,默认5min。如果在该间隔内没消费完poll回的消息,就会触发重平衡

最佳实践session.timeout.ms尽可能是heartbeat.interval.ms的三倍

  • session.timeout.ms: 6s
  • heartbeat.interval.ms: 2s
  • max.poll.interval.ms:建议大于消费者处理消息最长耗时

五、Q&A

1、重平衡时分配消费者的顺序是怎样的?

重平衡时分配消费者是按照消费组名的字典排序去进行分配的,如consumerA分配时会比consumerB先分配到分区


文章作者: GaryLee
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 GaryLee !
  目录