1. 概念
- Rebalance是让Consumer Group下所有的Consumer实例就如何消费订阅主题的所有分区达成共识的过程
- 在Rebalance过程中,所有Consumer实例共同参与,在协调者组件的帮助下,完成订阅主题分区的分配
- 整个Rebalance过程中,所有Consumer实例都不能消费任何消息,因此对Consumer的TPS影响很大
2. reblance弊端
- Rebalance影响Consumer端TPS
- Rebalance很慢
- Rebalance效率不高
每次Rebalance,Consumer Group下所有成员都需要参与,而且不考虑局部性原理,之前的分配方案都不会被保留
为了解决这个问题,社区于0.11.0.0版本推出StickyAssignor,即粘性的分区分配策略
- 粘性指的是每次Rebalance,都尽可能地保留之前的分配方案,尽量实现分区分配的最小改动
- 但该策略存在一些Bug,而且需要升级到0.11.0.0才能使用,实际生产环境中用得不多
- 影响Consumer端TPS + 慢属于无解,因此尽量减少不必要的Rebalance
3. reblance 触发时机
(1) 组成员数量发生变化
- Consumer实例增加:一般是基于增加TPS或者提高伸缩性的需要,属于计划内的操作,不属于不必要的Rebalance
- Consumer实例减少:在某些情况下Consumer实例会被Coordinator错误地认为已停止而被踢出Consumer Group
(2) 订阅主题数量发生变化
- 一般是运维主动操作,很难避免 (3) 订阅主题的分区数量发生变化
- 一般是运维主动操作,很难避免
4. consumer 端参数
(1) 当Consumer Group完成Rebalance后,每个Consumer实例都会定期地向Coordinator发送心跳
(2) 如果某个Consumer实例不能及时地发送心跳
- Coordinator会认为该Consumer已死,并将其从Consumer Group中移除,开启新一轮的Rebalance
(3) Consumer端有一个参数
session.timeout.ms,默认值为10秒 - 如果Coordinator在10秒内没有收到Consumer Group下某个Consumer实例的心跳,就会认为该Consumer已死
(4) Consumer端还有另一个参数
heartbeat.interval.ms,默认值为3秒 - 设置得越小,Consumer实例发送心跳的频率就会越高,会额外消耗带宽资源,但能更快地知道是否开启Rebalance
- Coordinator通过将REBALANCE_NEEDED标志封装进心跳响应中,来通知Consumer实例开启Rebalance
(5)Consumer端还有另一个参数
max.poll.interval.ms,默认值为5分钟 - 该参数用于控制Consumer实际消费能力对Rebalance的影响,限定了Consumer端两次调用poll方法的最大时间间隔
- Consumer如果在5分钟内无法消费完poll方法返回的消息,就会主动发起离开组的请求,开启新一轮的Rebalance
5. 非必要的reblance
(1)Consumer未及时发送心跳,导致被踢出Consumer Group而引发的Rebalance
-
生产配置:
session.timeout.ms=6000+heartbeat.interval.ms=2000session.timeout.ms=6000:为了让Coordinator能够更快地定位已经挂掉的Consumer
-
session.timeout.ms > 3 * heartbeat.interval.ms(2)Consumer消费时间过长,主动发起离开组的请求而引发的Rebalance -
如果消费逻辑很重(如DB操作),可以将
max.poll.interval.ms设置得大一点
(3) 关注Consumer端的GC表现,频繁的Full GC会引起非预期的Rebalance
参考文章