Kafka核心技术与实战
胡夕
人人贷计算平台部总监,Apache Kafka Contributor
立即订阅
8408 人已学习
课程目录
已完结 46 讲
0/4登录后,你可以任选4讲全文学习。
开篇词 (1讲)
开篇词 | 为什么要学习Kafka?
免费
Kafka入门 (5讲)
01 | 消息引擎系统ABC
02 | 一篇文章带你快速搞定Kafka术语
03 | Kafka只是消息引擎系统吗?
04 | 我应该选择哪种Kafka?
05 | 聊聊Kafka的版本号
Kafka的基本使用 (3讲)
06 | Kafka线上集群部署方案怎么做?
07 | 最最最重要的集群参数配置(上)
08 | 最最最重要的集群参数配置(下)
客户端实践及原理剖析 (14讲)
09 | 生产者消息分区机制原理剖析
10 | 生产者压缩算法面面观
11 | 无消息丢失配置怎么实现?
12 | 客户端都有哪些不常见但是很高级的功能?
13 | Java生产者是如何管理TCP连接的?
14 | 幂等生产者和事务生产者是一回事吗?
15 | 消费者组到底是什么?
16 | 揭开神秘的“位移主题”面纱
17 | 消费者组重平衡能避免吗?
18 | Kafka中位移提交那些事儿
19 | CommitFailedException异常怎么处理?
20 | 多线程开发消费者实例
21 | Java 消费者是如何管理TCP连接的?
22 | 消费者组消费进度监控都怎么实现?
深入Kafka内核 (5讲)
23 | Kafka副本机制详解
24 | 请求是怎么被处理的?
25 | 消费者组重平衡全流程解析
26 | 你一定不能错过的Kafka控制器
27 | 关于高水位和Leader Epoch的讨论
管理与监控 (12讲)
28 | 主题管理知多少?
29 | Kafka动态配置了解下?
30 | 怎么重设消费者组位移?
31 | 常见工具脚本大汇总
32 | KafkaAdminClient:Kafka的运维利器
33 | Kafka认证机制用哪家?
34 | 云环境下的授权该怎么做?
35 | 跨集群备份解决方案MirrorMaker
36 | 你应该怎么监控Kafka?
37 | 主流的Kafka监控框架
38 | 调优Kafka,你做到了吗?
39 | 从0搭建基于Kafka的企业级实时日志流处理平台
高级Kafka应用之流处理 (3讲)
40 | Kafka Streams与其他流处理平台的差异在哪里?
41 | Kafka Streams DSL开发实例
42 | Kafka Streams在金融领域的应用
结束语 (1讲)
结束语 | 以梦为马,莫负韶华!
特别放送 (2讲)
加餐 | 搭建开发环境、阅读源码方法、经典学习资料大揭秘
用户故事 | 黄云:行百里者半九十
Kafka核心技术与实战
登录|注册

25 | 消费者组重平衡全流程解析

胡夕 2019-07-30
你好,我是胡夕。今天我要和你分享的主题是:消费者组重平衡全流程解析。
之前我们聊到过消费者组的重平衡流程,它的作用是让组内所有的消费者实例就消费哪些主题分区达成一致。重平衡需要借助 Kafka Broker 端的 Coordinator 组件,在 Coordinator 的帮助下完成整个消费者组的分区重分配。今天我们就来详细说说这个流程。
先提示一下,我会以 Kafka 2.3 版本的源代码开启今天的讲述。在分享的过程中,对于旧版本的设计差异,我也会显式地说明。这样,即使你依然在使用比较旧的版本也不打紧,毕竟设计原理大体上是没有变化的。

触发与通知

我们先来简单回顾一下重平衡的 3 个触发条件:
组成员数量发生变化。
订阅主题数量发生变化。
订阅主题的分区数发生变化。
就我个人的经验来看,在实际生产环境中,因命中第 1 个条件而引发的重平衡是最常见的。另外,消费者组中的消费者实例依次启动也属于第 1 种情况,也就是说,每次消费者组启动时,必然会触发重平衡过程。
这部分内容我在专栏第 15 讲中已经详细介绍过了,就不再赘述了。如果你不记得的话,可以先去复习一下。
今天,我真正想引出的是另一个话题:重平衡过程是如何通知到其他消费者实例的?答案就是,靠消费者端的心跳线程(Heartbeat Thread)
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《Kafka核心技术与实战》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(55)

  • LRocccccc 置顶
    是我理解错了么?为什么场景一二三的图中的SyncGroup请求,都是等待Leader分配方案,leader不应该提供方案么?

    作者回复: 嗯嗯,确实是。只是目前Kafka要求所有consumer都发送SyncGroup请求给Coordinator,因为分配方案只能通过SyncGroupResponse的方式获取。图中只是想表示这是一种机制,没有太区分consumer leader和其他consumer

    2019-08-02
  • rm -rf 😊ི 置顶
    老师,在Broker 端重平衡场景剖析这个第一个图里面,既然协调者说了成员2是这个组的leader,为啥成员2的SyncGroup请求会是”等待leader分配“?这是笔误吗?后面几幅图好像也这样。。。

    作者回复: 只是想表明这是统一的一种机制。。。源代码中肯定没有这样的话。。。

    2019-07-31
  • ban
    不会超过 session.timeout.ms 就能感知

    老师,请问下,消费者已经崩溃了,不会发送心跳,协调者这时候怎么做到能到session.timeout.ms感知的。

    作者回复: 每次consumer发送心跳时会顺带发送session timeout时间,这样Coordinator收到后会根据这个session timeout时间计算下次deadline时间,如果过了deadline还没有收到直接fail掉该consumer

    2019-08-01
    7
  • Frank
    这节课,干货很多,我现在有个疑问,重平衡时需要从消费者实例中选择一个leader,让leader来发起重平衡方案,那为啥不直接让协调者组件来处理呢?

    作者回复: 客户端自己确定分配方案有很多好处。比如可以独立演进和上线,不依赖于服务器端

    2019-08-06
    4
  • DFighting
    重平衡能不能参照JVM中的Minor gc和Major gc,将重平衡分为两步,在资源的角度讲集群进行分区,这里的资源可以理解为分区,因为后两种变化都是涉及到分区——新主题或已有主题的分区数量变化,对于现有的三种重平衡情况分别做如下处理:
    1、新成员入区,在当前区内进行重平衡,不要影响其他的分区
    2、资源分区中需要消费的分区队列数量发生的变化,也只是涉及到当前分区的重平衡。
    这样设计的话就需要处理一个资源分区太空闲和太繁忙时的问题,我觉得可以参考m树的节点分裂和合并,这么做比m树更简单,因为它没有层级关系,只是资源分区的整合和划分而已,实现的时候还能兼顾到网络的局部特性,当然这只是初步想法,没有详细设计和验证,不知道有没有什么地方没有考虑周全,望老师能指点一二。

    作者回复: 嗯嗯,非常赞的思路。现在社区正在对rebalance进行改革中有很多思想和你也有重合之处。

    2019-09-09
    3
  • 明翼
    老师有两个问题请教下:
    1)组状态在empty的时候,删除位移信息,这个时间间隔(文中7天)是否可以配置那,还是和普通的默认topic的消息存活时间一样吗?
    2)这个设计我有点迷糊,都有协调者了为什么不让协调者统一做订阅分配那,让领导者做不是更麻烦吗?

    作者回复: 1. 可以配置offsets.retention.minutes
    2. 新版本consumer的一个改进就是把分区分配策略从server端移到consumer端来做。Client端代码演进的速度和容易程度要远胜于服务器端,算是一个优势吧

    2019-07-30
    3
  • Geek_edc612
    胡老师有没有推荐的jvm 书籍?这块一直没有深入看过

    作者回复: 我可不敢误人子弟:) 看看R大推荐的书单吧:https://www.douban.com/doulist/2545443/

    2019-07-30
    1
    2
  • cricket1981
    SyncGroup请求处理流程图中怎么出现了JoinGroup请求?是不是笔误?另外,新成员入组流程图中成员2的SyncGroup请求不应该是“协调者你好,我是成员2,也是这个组的领导者,这是我的分配方案...”吗?

    作者回复: 感谢纠正,已修改~~

    2019-07-30
    2
  • 巧克力黑
    老师你好,真实场景中遇到如下问题,请教一下。
    跑了一整天的数据,同离线数据按小时粒度相比,大部分小时能对齐数据,查看数据对不起的那个小时的消费者日志,发现如下log,
    19/10/15 22:46:00 ERROR ConsumerCoordinator: Offset commit failed.
    19/10/15 22:46:00 INFO AbstractCoordinator: (Re-)joining group test_group
    rebalance会造成数据丢失么? 是因为这种rebalance造成的数据丢失?

    作者回复: 不会造成数据丢失,但可能造成数据重复消费。

    2019-10-18
    1
  • 巧克力黑
    多次执行语句:kafka-consumer-groups.sh --bootstrap-server host1:9092 --describe --group group_v1
    发现CONSUMER-ID一列,有时候只显示"-",而且每次CONSUMER-ID的值也不相同。是不是就说明发生了重平衡?

    作者回复: 显示-是因为消费者有成员没有启动的缘故。另外每次consumer-id不同的确表明每次都是新的member

    2019-09-29
    1
  • QQ怪
    这一节学到了很多很多,开了视野,感谢
    2019-07-30
    1
  • Li Shunduo
    请问当重平衡开启时,协调者会给予提交位移的缓冲时间是多少?如果超过了会拒绝提交的位移吗?

    作者回复: 没有具体的限制。反正如果consumer提交的位移请求到broker端时整个group已经从Preparing进化到Completing了,那么就晚了,broker会拒绝这个提交请求

    2019-07-30
    1
  • Stony.修行僧
    有一个问题:Joingroup响应(成员2,你是这组的leader),Syncgroup请求(我是组员2,请求leader分配方案)。成员2已经是leader了,那么syncgroup的请求信息有点费解,明明已经是leader 还要请求leader分配方案?

    作者回复: 至少这样能统一机制,因为目前非leader consumer依赖SyncGroup请求才能获取分配方案

    2019-07-30
    1
  • pain
    文中有一句话:Kafka 定期自动删除过期位移的条件就是,组要处于 Empty 状态。因此,如果消费者组停掉了很长时间,那么 Kafka 很可能就把该组的位移数据删除了

    我记得好像默认 7 天会删除消息的啊,为什么一定要 empty 状态呢?不是 empty 状态,过期的就不删除吗

    作者回复: 是的,不是empty就不删除

    2019-11-23
  • James
    老师.好像没有说到订阅主题的分区数发生变化.
    分区数变化是指broker挂了,或新增吗.

    作者回复: 分区数变化是指topic增加了分区

    2019-11-13
  • 注定非凡
    1 重平衡的通知
    A :重平衡过程通过消息者端的心跳线程(Heartbeat Thread)通知到其他消费者实例。
    B :Kafka Java消费者需要定期地发送心跳请求到Broker端的协调者,以表明它还存活着。
    (1)在kafka 0.10.1.0版本之前,发送心跳请求是在消费者主线程完成的,也就是代码中调用KafkaConsumer.poll方法的那个线程。
    这样做,消息处理逻辑也是在这个线程中完成的 ,因此,一旦消息处理消耗了过长的时间,心跳请求将无法及时发到协调者那里,导致协调者错判消费者已死。
    (2)在此版本后,kafka社区引入了单独的心跳线程来专门执行心跳请求发送,避免这个问题。
    C :重平衡的通知机制是通过心跳线程来完成的,当协调者决定开启新一轮重平衡后,他会将“REBALANCE_IN_PROGRESS”封装进心跳请求的响应中,发还给消费者实例。当消费者实例发现心跳响应中包含了”REBALANCE_IN_PROGRESS”,就能立即知道重平衡开始了。
    D :消费者端的参数 heartbeat.interval.ms的真实用途是控制重平衡通知的频率。

    2 消费者组状态机
    Kafka设计了一套消费者组状态机(State Machine),帮助协调者完成整个重平衡流程。
    A :kafka消费者组状态
    (1)Empty:组内没有任何成员,但消费者组可能存在已提交的位移数据,而且这些位移尚未过期。
    (2)Dead:组内没有任何成员,但组的元数据信息已经在协调者端被移除。协调者保存着当前向它注册过的所有组信息,所谓元数据就是类似于这些注册信息。
    (3)PreparingRebalance:消费者组准备开启重平衡,此时所有成员都要重新请求加消费者组
    (4)CompletingRebalance:消费者组下所有成员已经加入,各个成员正在等待分配方案。
    (5)stable:消费者组的稳定状态。该状态表明重平衡已经完成,组内成员能够正常消费数据了。

           B :Kafka定期自动删除过期位移的条件就是,组要处于Empty状态。如果消费者组停了很长时间(超过7天),那么Kafka很可能就把该组的位移数据删除了。

    3 消费者端重平衡流程
    A :重平衡的完整流程需要消费者端和协调者组件共同参与才能完成。
    B :在消费者端,重平衡分为两个步骤:
    (1)加入组,对应请求:JoinGroup请求
    (2)等待领导者消费者分配方案:SyncGroup请求
    C :当组内成员加入组时,他会向协调者发送JoinGroup请求。在该请求中,每个成员都要将自己订阅的主题上报,这样协调者就能收集到所有成员的订阅信息。一旦收集了全部成员的JoinGroup请求后,协调者会从这些成员中选择一个担任这个消费者组的领导者。
    D :通常情况下,第一个发送JoinGroup 请求的成员自动成为领导者。这里的领导者是具体的消费者实例,它既不是副本,也不是协调者。领导者消费者的任务是收集所有成员的订阅信息,然后根据这些信息,制定具体的分区消费分配方案。
    E :选出领导者之后,协调者会把消费者组订阅信息封装进JoinGroup请求的响应中,然后发给领导者,由领导统一做出分配方案后,进入下一步:发送SyncGroup请求。
    F :领导者向协调者发送SyncGroup请求,将刚刚做出的分配方案发给协调者。值得注意的是,其他成员也会向协调者发送SyncGroup请求,只是请求体中并没有实际内容。这一步的目的是让协调者接收分配方案,然后统一以SyncGroup 响应的方式发给所有成员,这样组内成员就都知道自己该消费哪些分区了。

    4 Broker端重平衡场景剖析

    A :新成员入组
    当协调者收到新的JoinGroup请求后,它会通过心跳请求响应的方式通知组内现有的所有成员,强制他们开启新一轮的重平衡。
    B :组成员主动离组
    消费者实例所在线程或进程调用close()方法主动通知协调者他要退出。这个场景涉及第三类请求:LeaveGroup请求。协调者收到LeaveGroup请求后,依然会以心跳响应的方式通知其他成员。
    C :组成员崩溃离组
    崩溃离组是指消费者实例出现严重故障,突然宕机导致的离组。崩溃离组是被动的,协调者通常需要等待一段时间才能感知,这段时间一般是由消费者端参数session.timeout.ms控制的。
    D :重平衡时协调者对组内成员提交位移的处理
    正常情况下,每个组内成员都会定期汇报位移给协调者。当重平衡开启时,协调者会给予成员一段缓冲时间,要求每个成员必须在这段时间内快速地上报自己的位移信息,然后在开启正常JoinGroup/SyncGroup请求发送。
    2019-11-08
  • rhwayfun
    线上遇到一个问题,消费组扩容机器100台,直接把broker打挂了,从重平衡的流程看,是因为
    2019-11-01
  • 兔2🐰🍃
    作者回复: 每次consumer发送心跳时会顺带发送session timeout时间,这样Coordinator收到后会根据这个session timeout时间计算下次deadline时间,如果过了deadline还没有收到直接fail掉该consumer

    老师说“Kafka 一般不会超过 session.timeout.ms 就能感知到这个崩溃”,感觉上面回复中的 session timeout 要小于这个消费者端参数,那么心跳请求里的session timeout 是什么计算的?

    作者回复: 这块需要更正一次,不是在心跳时携带的session timeout,这个时间在加入组的时候就已经发给Coordinator了。

    2019-10-24
  • 绿箭侠
    老师,看前面也有人问为啥不把订阅分配方案移到协调者上统一去做? 您说Client端代码演进速度 和 容易程度远胜于服务器端,是一个优势。
    这里还是没明白,为什么Client端代码演进速度 和 容易程度更好?!!

    作者回复: 这只是其中的一个可能的原因。client端代码更新的难度要远小于broker端。如果是broker代码更新,你需要rolling upgrade所有集群中的broker,在生产环境中并不一定有这样的时间窗口

    2019-10-21
  • 心如大海,春暖花开
    消费组状态dead,先提及是组元数据信息被协调者删除,后面又说到协调者保存元数据信息?

    作者回复: Dead状态下Coordinator会把组的数据删除。这和后面的表述有什么冲突的地方吗?没太明白您的意思。

    2019-10-18
收起评论
55
返回
顶部