Kafka重平衡机制

4,622 阅读4分钟

这是我参与8月更文挑战的第3天,活动详情查看:8月更文挑战

重平衡的作用

让消费者分组内消费者消费哪些主题分区达成一致。重平衡需要借助Kafka Broker端的Coordinator组件,在Coordinator的帮助下完成消费者组的分区重新分配。

触发重平衡的三个条件

  1. 组内成员数量发生变化
  2. 消费者组订阅主题的数量发生变化
  3. 订阅主题的分区数量发生变化。

重平衡的流程

重平衡是通过消费者端的心跳线程通知其他的消费实例发生重平衡。重平衡开启后,borker通过维护一套消费者组状态机来协调完成整个重平衡机制。

消费者的五种状态

状态含义
Empty组内没有任何成员,但是消费者可能存在已提交的位移数据,而且这些唯一尚未过期
Dead同样是组内没有任何成员,但是组的元数据信息已经被协调者端移除,协调者保存着当前向他注册过的所有组信息
PreparingRebalance消费者组准备开启重平衡,此时所有成员都需要重新加入消费者组
CompletingRebalance消费者组下所有成员已经加入,各个成员中等待分配方案
Stable消费者组的稳定状态,该状态表明重平衡已经完成,组内成员能够正常消费数据

五种状态的流转

image.png

  1. 一个消费者组最开始是 Empty 状态,当重平衡过程开启后,它会被置于 PreparingRebalance 状态等待成员加入,之后变更到 CompletingRebalance 状态等待分配方案,最后流转到 Stable 状态完成重平衡。

  2. 当有新成员加入或已有成员退出时,消费者组的状态从 Stable 直接跳到 PreparingRebalance 状态,此时,所有现存成员就必须重新申请加入组。当所有成员都退出组后,消费者组状态变更为 Empty。

详细流程

在消费者端,重平衡分为两个步骤:分别是加入组和等待领导者消费者(Leader Consumer)分配方案。这两个步骤分别对应两类特定的请求:JoinGroup 请求和 SyncGroup 请求。

  1. 当组内成员加入组时,它会向协调者发送 JoinGroup 请求。在该请求中,每个成员都要将自己订阅的主题上报,这样协调者就能收集到所有成员的订阅信息。一旦收集了全部成员的 JoinGroup 请求后,协调者会从这些成员中选择一个担任这个消费者组的领导者。领导者消费者的任务是收集所有成员的订阅信息,然后根据这些信息,制定具体的分区消费分配方案。

  2. 选出领导者之后,协调者会把消费者组订阅信息封装进 JoinGroup 请求的响应体中,然后发给领导者,由领导者统一做出分配方案后,领导者向协调者发送 SyncGroup 请求,将刚刚做出的分配方案发给协调者。

  3. 其他成员也会向协调者发送 SyncGroup 请求,只不过请求体中并没有实际的内容。这一步的主要目的是让协调者接收分配方案,然后统一以 SyncGroup 响应的方式分发给所有成员,这样组内所有成员就都知道自己该消费哪些分区了。

Broker端重平衡流程

场景一:新成员加入

当协调者收到新的 JoinGroup 请求后,它会通过心跳请求响应的方式通知组内现有的所有成员,强制它们开启新一轮的重平衡。具体的过程和之前的客户端重平衡流程是一样的。

image.png

场景二:成员主动离组

消费者实例所在线程或进程调用 close() 方法主动通知协调者它要退出。这个场景就涉及到了第三类请求:LeaveGroup 请求。协调者收到 LeaveGroup 请求后,依然会以心跳响应的方式通知其他成员

image.png

场景三:组成员崩溃离组

他和成员主动离组的区别是它属于被动离开,broker端不知道成员离组,经过心跳超时后,判定成员离组的一种情况。

image.png