消费者组的重平衡流程 : 让组内所有的消费者消费哪些主题分区达成一致

  • 重平衡要在 Coordinator 协助下完成整个消费者组的分区重分配

触发与通知

重平衡的 3 个触发条件:

  • 组成员数量发生变化
  • 订阅主题数量发生变化
  • 订阅主题的分区数发生变化

重平衡过程通知其他消费者 : 靠消费者端的心跳线程 (Heartbeat Thread)

消费者会定期发送心跳请求 (Heartbeat Request) 到 Broker 的协调者,来表明存活

  • Kafka 0.10.1.0 前,发送心跳请求是在消费者主线程完成的,用 KafkaConsumer.poll 的那个线程
  • Kafka 0.10.1.0 后,用单独的心跳线程来专门执行心跳请求发送

重平衡的通知机制 : 通过心跳线程来完成

  • 当协调者要开启重平衡,会将 REBALANCE_IN_PROGRESS 封装进心跳请求的响应中,发给消费者
  • 当消费者实例发现心跳响应中包含 REBALANCE_IN_PROGRESS ,就得知开始重平衡

heartbeat.interval.ms : 控制重平衡通知的频率

  • 要消费者更快通知,就调小点,让消费者更快感知到重平衡开启

消费者组状态机

Kafka 有一套消费者组状态机 (State Machine),来帮助协调者完成重平衡

消费者组的 5 种状态 :

状态

含义

Empty

组内没有成员,但消费者组还存在已提交的位移数据,且这些位移尚未过期

Dead

组内没有成员,但组的元数据信息已经在协调者被移除。协调者组件保存着当前向它注册过的所有组信息

PreparingRebalance

消费者组准备重平衡,所有成员要重新请求加入消费者组

CompletingRebalance

消费者组下所有成员已经加入,各个成员等待分配方案(老版本 : AwaitingSync)

Stable

消费者组的稳定状态 : 重平衡已经完成,组内各成员能正常消费数据

状态机的各状态流转 :

  • 消费者组最开始是 Empty 状态
  • 当重平衡开始,以 PreparingRebalance 状态等待成员加入
  • 变成 CompletingRebalance 状态等待分配方案
  • 再转成 Stable 状态完成重平衡
  • 当新成员加入或已有成员退出时,消费者组的状态从 Stable 直接跳到 PreparingRebalance 状态:所有现存成员要重新申请加入组
  • 当所有成员都退出组后,消费者组会变为 Empty
  • Kafka 定期自动删除过期位移的条件:组要在 Empty 状态 (当消费者组停了 (超过 7 天) : Kafka 可能把该组的位移数据删除)

日志的输出:尝试定期删除过期位移

  • 只有 Empty 状态的组,才能执行过期位移删除

Removed ✘✘✘ expired offsets in ✘✘✘ milliseconds.

kafka heartbeat kafka heartbeat lost_kafka heartbeat

消费者重平衡流程

消费者的重平衡两个步骤:

  • 加入组 , 等待领导者消费者 (Leader Consumer) 分配方案
  • 两个步骤分别对应请求:JoinGroup 请求 , SyncGroup 请求

JoinGroup 请求的处理过程 :

  • JoinGroup 作用 : 将组成员订阅信息发送给领导者消费者 (通常 : 第一个发送 JoinGroup 的成员是领导者),等领导者分配好方案后,重平衡进入到 SyncGroup 阶段

kafka heartbeat kafka heartbeat lost_kafka heartbeat_02

SyncGroup 请求的处理流程 :

  • SyncGroup 目的 : 让协调者把领导者的分配方案发给各个组内成员
  • 当所有成员都成功接收到分配方案后,消费者组进入到 Stable 状态 (正常消费)

kafka heartbeat kafka heartbeat lost_redis_03

Broker 重平衡场景

新成员入组

新成员入组 : 组处于 Stable 状态后,有新成员加入

  • 当协调者收到新 JoinGroup 后,会通过心跳请求通知组内所有成员,强制开启重平衡

kafka heartbeat kafka heartbeat lost_java_04

组成员主动离组

主动离组 : 消费者调用 close() 主动通知协调者要退出

  • 协调者收到 LeaveGroup 后,以心跳响应通知其他成员

kafka heartbeat kafka heartbeat lost_kafka heartbeat_05

组成员崩溃离组

崩溃离组 : 消费者挂了,而导致离组

  • 崩溃离组是被动,协调者要等待时间 (session.timeout.ms) 才能感知

kafka heartbeat kafka heartbeat lost_kafka heartbeat_06

重平衡提交位移

  • 当重平衡开启时,要求每个成员要时间内快速上报各自位移信息
  • 再开始 JoinGroup/SyncGroup 请求发送

kafka heartbeat kafka heartbeat lost_分布式_07