21、Kafka实战:消费者组重平衡

一.重平衡的触发条件:

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

组成员数据发生变化引发的重平衡最常见

产生原因:

  • 消费者组内的消费者实例依次启动也属于第1种情况
  • 每次消费者组启动都会触发重平衡

二.消费者端的心跳线程(Heartbeat Thread)

  • Kafka Java消费者需要定期发送心跳请求(Heartbeat Request)到Broker端的协调者
  • 以证明他还存活
  • kafka 0.10.1.0版本之前,发送心跳请求是在消费者主线程完成的,也就是KafkaConsumer.poll 方法

存在问题:

  • 消息处理逻辑也是在这个线程中完成的
  • 一旦消息处理消耗过长时间,心跳请求将无法及时发到协调者哪里,导致协调者错误的认为该消费者已死
  • 0.10.1.0 版本以后,社区专门引入单独的心跳线程执行心跳请求发送,避免这个问题。

三.重平衡通知机制

  • 重平衡通知机制通过心跳线程来完成
  • 协调者决定开启新一轮重平衡后会将”RANCE_IN_PROGRESS"封装金心跳请求的响应中,发送还给消费者实例
  • 消费者实例发现心跳响应中包含**"REBALANCE_IN_PROGRESS"**,就立马知道重平衡又开始了

四.消费者端参数heartbeat.interval.ms

  • 设置心跳的间隔时间
  • 这个参数真正作用是控制重平衡通知的频率
  • 如果调低参数值,消费者机会更快的感知重平衡

五.消费者组状态机

  • kafka为消费者组定义了5种状态:Empty,Deal,PreparingRebalance,CompletingRebalance和Stable
消费者组的5种状态
状态 含义
Empty 组内没有任何成员,但是消费者组存在已经提交的位移数据,而且这些位移尚未过期
Dead 组内没有任何成员,但组内的元信息吗,已经被移除。协调者组件保存者当前向他组测过的所有组件信息。所谓的元数据信息就类似于这个信息。
PreparingRebalance 消费组组准备开启重平衡,所有消费者都要重新请求加入消费者组
CompletingRebalance 消费者组各成员已加入,正在等待分配方案
Stable 消费者组状态稳定,该状态表示重平衡已经完成,各组成员能够正常消费数据

六.状态机各个状态流转

*

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

当新成员加入或已有成员推出时候

  • 消费者组的状态从Stable直接跳到PrearingREbalance状态,此时所有现存成员必须重新申请加入组
  • 当所有成员都退出组后,消费者组状态就变更为Empty
  • Kafak定期删除过期位移的条件是,组要处于Empty状态
  • 因此,如果消费者组停掉超过7天,该组位移数据就删除了。

七.消费者端重平衡流程

  • 加入组 JoinGroup请求
  • 等待领导者消费者(Leader Consumer)分配方案 SyncGroup请求

八.JoinGroup请求

  • 当组内成员加入组时,他会向协调者发送JoinGroup请求。
  • 该请求中每个成员都要将自己订阅的主题上报,这样协调者就能收集到所有成员的订阅信息
  • 一旦收集了全部成员的JoinGroup 请求后,协调者会从这些成员中选择一个担任这个消费者组的领导者。

领导者消费者的任务是收集所有成员的订阅信息,然后根据这些信息,制定具体的分区消费分配方案。

九.发送SyncGroup请求

  • 选出领导者知乎,协调者=吧消费者组订阅信息封装斤JoinGroup请求的响应体中,然后 在发给领导者
  • 由领导者统一做出分配方案后,进入下一步:发送SyncGroup请求

*

*

SyncGroup请求目的:协调者把领导者指定的分配方案发给各个组内成员,所有成员成功接收到分配方案后,消费者组进入到Stabal状态,即开始正常的消费工作。

十.Broker端重平衡场景剖析

场景一:新成员入组

*

场景二:组成员主动离组

主动离组:指消费者实例所在线程或者进程调用close()方法主动通知协调者它要退出

LeaveGroup请求

*

组成员崩溃离组

消费者实例出现严重故障,突然宕机导致的离组

*

版权声明:本文不是「本站」原创文章,版权归原作者所有 | 原文地址: