Kafka Rebalance 机制
触发 Rebalance 的时机
Rebalance 发生的本质是消费者组成员或订阅信息发生了变化,导致原有的分区分配不再有效。具体触发时机有三类:
1.消费者组成员数量变化
新消费者加入:当一个新的消费者实例加入消费者组时,需要重新分配分区以让新消费者接管部分负载。 消费者主动离开:消费者正常关闭时,会主动通知协调器离开组。 消费者崩溃/失联:消费者在 session.timeout.ms 内未发送心跳,或在 max.poll.interval.ms 内未调用 poll() 方法,协调器会将其踢出组。
2. 订阅信息变化
订阅主题变更:消费者通过 subscribe() 方法订阅了新的主题,或取消了订阅。
正则表达式订阅匹配到新主题:如果使用正则表达式订阅(如 subscribe("topic.*")),当创建了与该正则表达式匹配的新主题时,会触发 Rebalance。
3. 分区数量变化
-
被订阅主题的分区数增加:管理员增加了主题的分区数,导致现有分配无法覆盖所有分区,触发 Rebalance。
Rebalance 的原理
Rebalance 本质是一个协调协议,主要由消费者组协调器(Group Coordinator,服务端的一个 Broker)和消费者共同完成。
1. 核心角色
Group Coordinator:每个消费者组在服务端都有一个对应的 Broker 作为协调器。它负责管理组成员、处理心跳、选举 Leader 以及执行 Rebalance。 Group Leader:消费者组内第一个加入的消费者,或由协调器选出的一个消费者。Leader 负责制定分区分配方案,而其他消费者(Follower)只需接受该方案。
2. 状态机
每个消费者组在协调器上维护一个状态机,Rebalance 是状态流转的核心过程:
Empty:组内无活跃消费者,可能有已提交的位移。 Preparing Rebalance(准备重平衡):当触发条件发生时,组进入此状态。协调器向所有消费者发送 JoinGroup 请求,等待成员加入。 Awaiting Sync(等待同步):所有消费者加入后,选举出 Leader,由 Leader 制定分配方案并通过 SyncGroup 请求发送给协调器。 Stable(稳定):所有消费者成功同步分配方案后,组进入稳定状态,正常消费。
3. 详细流程(两阶段协议)
Rebalance 分为 JoinGroup 阶段和 SyncGroup 阶段:
第一阶段:JoinGroup(加入组)
1.所有消费者向协调器发送 JoinGroup 请求。 2.协调器收集所有成员的 JoinGroup 请求。 3.在收集齐所有现有成员(或超时后),协调器从成员中选举出 Group Leader。 4.协调器向所有成员返回 JoinGroup 响应,其中包含组成员信息和 Leader 身份标识。普通成员收到后知道自己不是 Leader,等待下一步;Leader 则知道自己需要制定分配方案。
JoinGroup 请求是消费者主动向协调器发起的,虽然 Rebalance 的触发条件(如消费者宕机、新成员加入等)是由协调器(Group Coordinator) 检测并决策的,但实际的协议交互动作,包括 JoinGroup 和 SyncGroup,都是由消费者客户端主动发送请求来完成的。
消费者主动发起 JoinGroup 的两种核心场景:
1. 启动时的主动加入:当消费者首次启动并调用 poll() 方法时,它发现当前还没有加入任何消费者组。
2.当协调器决定开启新一轮 Rebalance 时,它不会直接给消费者发“开始 Rebalance”的命令。而是采用通知机制:
协调器侧:当协调器检测到条件变化(如成员超时),它会更新组的状态为 PreparingRebalance。 消费者侧:消费者通过心跳线程定期发送 Heartbeat 请求。 如果心跳响应中,协调器返回的错误码是 REBALANCE_IN_PROGRESS(表示组正在重平衡), 消费者收到此错误后,会主动中断当前消费,并立即发起 JoinGroup 请求 来重新加入组。
第二阶段:SyncGroup(同步组)
1.Leader 制定方案:Leader 根据组内所有成员的订阅信息,调用配置的分区分配策略(如 RangeAssignor、RoundRobinAssignor、StickyAssignor、CooperativeStickyAssignor)计算分配结果。 2.Leader 将分配方案封装在 SyncGroup 请求中发送给协调器。 3.所有其他消费者(Follower)也发送一个空的 SyncGroup 请求。 4.协调器收到 Leader 的分配方案后,将方案分别返回给各个消费者。 5.每个消费者根据收到的分配结果开始消费分区。
4. 关键机制与优化
-
心跳机制与超时:消费者后台线程持续向协调器发送心跳。如果
session.timeout.ms内未收到心跳,协调器判定消费者死亡,触发 Rebalance。max.poll.interval.ms用于防止消费者处理业务逻辑过慢,如果两次poll()间隔超时,协调器也会将其踢出。 -
Epoch 机制(防止脑裂):每次 Rebalance 后,协调器会为消费者组生成一个新的 Generation(代数)。消费者在提交位移时必须携带该代数。如果某个消费者因网络延迟使用了旧的代数提交位移,协调器会拒绝,防止已离开的消费者错误地覆盖位移。
-
增量式 Rebalance(Cooperative Rebalance):从 Kafka 2.4 开始,引入了
CooperativeStickyAssignor。传统的 Rebalance 是“停止-等待”式的,会造成短暂的“Stop-The-World”消费停顿。增量式 Rebalance 允许仅重新分配那些必须移动的分区,未受影响的分区继续消费,减少了 Rebalance 对延迟敏感应用的影响。

浙公网安备 33010602011771号