Kafka -- 重平衡

触发重平衡

  1. 组成员数量发生变化 – 最常见
  2. 订阅主题数量发生变化
  3. 订阅主题的分区数发生变化

通知

  1. 重平衡过程是通过消费者的心跳线程通知到其它消费者实例的
  2. Kafka Java消费者需要定期地发送心跳请求到Broker端的协调者,表明它还活着
  3. 在Kafka 0.10.1.0之前,发送心跳请求是在消费者主线程完成的,即调用poll方法的那个线程
    • 弊端
      • 消息处理逻辑是也在主线程完成的
      • 一旦消息处理消耗了很长时间,心跳请求将无法及时发送给协调者,导致协调者误以为消费者已死
    • 从Kafka 0.10.1.0开始,社区引入了单独的心跳线程
  4. 重平衡的通知机制是通过心跳线程来完成的
    • 当协调者决定开启新一轮重平衡后,会将REBALANCE_IN_PROGRESS封装进心跳请求的响应
    • 当消费者实例发现心跳响应中包含REBALANCE_IN_PROGRESS,就知道重平衡要开始了,这是重平衡的通知机制
  5. heartbeat.interval.ms的真正作用是控制重平衡通知的频率

消费者组状态机

状态 描述
Empty 组内没有任何成员,但消费者组可能存在已提交的位移数据,而且这些位移尚未过期
Dead 组内没有任何成员,但组的元数据已经在协调者端被移除,协调者组件保存着当前向它注册过的所有组信息
PreparingRebalance 消费者组准备开启重平衡,此时所有成员都要重新请求加入消费者组
CompletingRebalance 消费者组下所有成员已经加入,各个成员正在等待分配方案
该状态在老版本中称为AwaitingSync,与CompetingRebalance是等价的
Stable 消费者组的稳定状态,该状态表明重平衡已经完成,组内各成员都能够正常消费数据
  1. 一个消费者组最开始是Empty状态,当重平衡过程开启后,会被置于PreparingRebalance状态等待成员加入
    • 之后变更到CompletingRebalance状态等待分配方案,最后流转到Stable状态完成重平衡
  2. 当有新成员加入或已有成员退出时,消费者组的状态从Stable直接跳到PreparingRebalance状态
    • 所有现存成员都必须重新申请加入组
  3. 当所有成员都退出组后,消费者组状态变更为Empty
    • Kafka定期自动删除过期位移的条件是消费者组要处于Empty状态
    • Removed ✘✘✘ expired offsets in ✘✘✘ milliseconds

重平衡流程

重平衡流程需要消费者端协调者组件共同参与才能完成

消费者端

  1. 在消费者端,重平衡分为两个步骤:加入组等待领导者消费者(Leader Consumer)分配方案
    • 分别对应两类特定的请求:JoinGroup请求SyncGroup请求
  2. 当组内成员加入组时,会向协调者发送JoinGroup请求
    • 在JoinGroup请求中,每个成员都要将自己订阅的主题上报,这样协调者就能收集所有成员的订阅信息
    • 一旦收集了全部成员的JoinGroup请求后,协调者会从这些成员中选择一个担任这个消费者组的领导者
      • 通常请求下,第一个发送JoinGroup请求的成员会自动成为领导者
      • 这里的领导者与领导者副本不是一个概念,这里的领导者是具体的消费者实例
    • 消费者领导者的职责:收集所有成员的订阅信息,然后根据这些信息,制定具体的分区消费分配方案
    • 选出领导者后协调者会把消费者组订阅信息封装进JoinGroup请求的响应体中,返回给领导者,由领导者统一分配
  3. 领导者向协调者发送SyncGroup请求,将刚刚做出的分配方案发给协调者
    • 其它成员也会向协调者发送SyncGroup请求,只不过请求体中并没有实际的内容
    • 让协调者接收分配方案,然后统一以SyncGroup响应的方式分发给所有成员

JoinGroup

  1. JoinGroup请求的主要作用是将组成员订阅信息发送给领导者消费者
  2. 待领导者制定好分配方案后,重平衡流程进入到SyncGroup请求阶段

SyncGroup

  1. SyncGroup请求的主要作用是让协调者把领导者制定的分配方案下发给各个组内成员
  2. 当所有成员都成功接收到分配方案后,消费者组进入Stable状态,即开始正常的消费工作

Broker端

新成员加入组

  1. 新成员加入组指的是消费者组处于Stable状态后,有新成员加入,而不是全新启动一个消费者组
  2. 当协调者收到新的JoinGroup请求后,会通过心跳请求响应的方式通知组内现有的所有成员,强制它们开启新一轮重平衡

组成员主动离组

  1. 主动离组:消费者实例所在的线程或者进程调用close()方法主动通知协调者它要退出,即LeaveGroup请求
  2. 协调者收到LeaveGroup请求后,依然会以心跳响应的方式通知其它成员

组成员崩溃离组

  1. 崩溃离组:消费者实例出现严重故障,突然宕机导致的离组
  2. 主动离组,协调者能马上感知并处理;崩溃离组,协调者需要等待一段时间才能感知到,参数session.timeout.ms

重平衡时协调者对组内成员提出位移的处理

  1. 正常情况下,每个组内成员都会定期汇报位移给协调者
  2. 当重平衡开启时,协调者会给予成员一段缓冲时间
    • 要求每个成员必须在这段缓冲时间内快速上报位移信息,然后再开启正常的JoinGroup/SyncGroup请求
0%