Kafka核心技术与实战——25 | 消费者组重平衡全流程解析

  • 消费者组的重平衡流程
    • 它的作用是让组内所有的消费者实例就消费哪些主题分区达成一致
    • 在 Coordinator 的帮助下完成整个消费者组的分区重分配
  • 重平衡的 3 个触发条件:
    • 1、组成员数量发生变化。
    • 2、订阅主题数量发生变化。
    • 3、订阅主题的分区数发生变化
    • 在实际生产环境中,因命中第 1 个条件而引发的重平衡是最常见的
    • 每次消费者组启动时,必然会触发重平衡过程
  • 重平衡过程是如何通知到其他消费者实例的?
    • 答案就是,靠消费者端的心跳线程(Heartbeat Thread)
    • 当协调者决定开启新一轮重平衡后,它会将“REBALANCE_IN_PROGRESS”封装进心跳请求的响应中,发还给消费者实例
  • 消费者端参数 heartbeat.interval.ms 的真实用途
    • 从字面上看,它就是设置了心跳的间隔时间,但这个参数的真正作用是控制重平衡通知的频率
    • 如果你想要消费者实例更迅速地得到通知,那么就可以给这个参数设置一个非常小的值,这样消费者就能更快地感知到重平衡已经开启了
  • 消费者组状态机
    • Kafka 设计了一套消费者组状态机(State Machine),来帮助协调者完成整个重平衡流程
  • 消费者组启动时的状态流转过程
    • 一个消费者组最开始是 Empty 状态,当重平衡过程开启后,它会被置于 PreparingRebalance 状态等待成员加入,之后变更到 CompletingRebalance 状态等待分配方案,最后流转到 Stable 状态完成重平衡
    • 当有新成员加入或已有成员退出时,消费者组的状态从 Stable 直接跳到 PreparingRebalance 状态,此时,所有现存成员就必须重新申请加入组
    • 当所有成员都退出组后,消费者组状态变更为 Empty
    • Kafka 定期自动删除过期位移的条件就是,组要处于 Empty 状态
    • 因此,如果你的消费者组停掉了很长时间(超过 7 天),那么 Kafka 很可能就把该组的位移数据删除了
  • 消费者端重平衡流程
    • 在消费者端,重平衡分为两个步骤:分别是加入组和等待领导者消费者(Leader Consumer)分配方案
    • 这两个步骤分别对应两类特定的请求:JoinGroup 请求和 SyncGroup 请求
  • Broker 端重平衡场景剖析
    • 重平衡的完整流程需要消费者端和协调者组件共同参与才能完成
    • 要剖析协调者端处理重平衡的全流程,我们必须要分几个场景来讨论
  • 场景一:新成员入组
    • 新成员入组是指组处于 Stable 状态后,有新成员加入。如果是全新启动一个消费者组,Kafka 是有一些自己的小优化的,流程上会有些许的不同。我们这里讨论的是,组稳定了之后有新成员加入的情形。
    • 当协调者收到新的 JoinGroup 请求后,它会通过心跳请求响应的方式通知组内现有的所有成员,强制它们开启新一轮的重平衡。具体的过程和之前的客户端重平衡流程是一样的。现在,我用一张时序图来说明协调者一端是如何处理新成员入组的
  • 场景二:组成员主动离组。
    • 何谓主动离组?就是指消费者实例所在线程或进程调用 close() 方法主动通知协调者它要退出。这个场景就涉及到了第三类请求:LeaveGroup 请求。协调者收到 LeaveGroup 请求后,依然会以心跳响应的方式通知其他成员,因此我就不再赘述了,还是直接用一张图来说明。
  • 场景三:组成员崩溃离组。
    • 崩溃离组是指消费者实例出现严重故障,突然宕机导致的离组。它和主动离组是有区别的,因为后者是主动发起的离组,协调者能马上感知并处理。但崩溃离组是被动的,协调者通常需要等待一段时间才能感知到,这段时间一般是由消费者端参数 session.timeout.ms 控制的。也就是说,Kafka 一般不会超过 session.timeout.ms 就能感知到这个崩溃。当然,后面处理崩溃离组的流程与之前是一样的,我们来看看下面这张图。
  • 场景四:重平衡时协调者对组内成员提交位移的处理。
    • 正常情况下,每个组内成员都会定期汇报位移给协调者。当重平衡开启时,协调者会给予成员一段缓冲时间,要求每个成员必须在这段时间内快速地上报自己的位移信息,然后再开启正常的 JoinGroup/SyncGroup 请求发送
  • 小结
posted @ 2020-06-01 14:30  怡情养性长智  阅读(380)  评论(0编辑  收藏  举报