一、什么是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
先分配到分区