透彻理解Kafka(九)——Consumer:协调器

作者简介:大家好,我是smart哥,前中兴通讯、美团架构师,现某互联网公司CTO

联系qq:184480602,加我进群,大家一起学习,一起进步,一起对抗互联网寒冬

学习必须往深处挖,挖的越深,基础越扎实!

阶段1、深入多线程

阶段2、深入多线程设计模式

阶段3、深入juc源码解析


阶段4、深入jdk其余源码解析


阶段5、深入jvm源码解析

码哥源码部分

码哥讲源码-原理源码篇【2024年最新大厂关于线程池使用的场景题】

码哥讲源码【炸雷啦!炸雷啦!黄光头他终于跑路啦!】

码哥讲源码-【jvm课程前置知识及c/c++调试环境搭建】

​​​​​​码哥讲源码-原理源码篇【揭秘join方法的唤醒本质上决定于jvm的底层析构函数】

码哥源码-原理源码篇【Doug Lea为什么要将成员变量赋值给局部变量后再操作?】

码哥讲源码【你水不是你的错,但是你胡说八道就是你不对了!】

码哥讲源码【谁再说Spring不支持多线程事务,你给我抽他!】

终结B站没人能讲清楚红黑树的历史,不服等你来踢馆!

打脸系列【020-3小时讲解MESI协议和volatile之间的关系,那些将x86下的验证结果当作最终结果的水货们请闭嘴】

每个消费者组都会选择一个Broker作为自己的Coordinator,这个GroupCoordinator协调器负责监控这个消费组里的各个消费者的心跳,判断它们是否宕机,如果宕机则进行Rebalance。

那么,这里就要思考几个问题:

  1. 消费者组应该选择哪一个Broker作为GroupCoordinator?
  2. GroupCoordinator是如何为它的消费者组进行Rebalance的?

一、GroupCoordinator

1.1 选择GroupCoordinator

我们先来看下消费者组是如何选择GroupCoordinator的。

我之前说过,每个Consumer在提交offset时,会将offset提交到__consumer_offsets这个内部Topic的某个分区上,默认分区数是50,事实上, Consumer提交offset的那个Leader分区所在的Broker就是GroupCoordinator 。

举个例子,假设有一个消费者组,groupId = membership-consumer-group

  1. Consumer启动的时候,会对groupId进行hash运算,然后与__consumer_offsets的分区数取模,得到一个数值;
  2. 消费者组下的所有Consumer在提交offset时,会提交到这个数值对应的__consumer_offsets的那个分区;
  3. 最终,上述Leader分区所在的Broker就是这个消费者组的GroupCoordinator,组里的消费者会维护Socket连接与这个Broker进行通信。

1.2 分区分配

确认GroupCoordinator后,我们再来看下分区分配是如何进行的。

  1. 初始时,消费者组内的每个Consumer都会发送JoinGroup请求到GroupCoordinator;
  2. GroupCoordinator会从消费组内选择一个Consumer作为Leader,然后把消费者组的情况发送给这个Leader;
  3. 消费者Leader会负责制定分区方案,并通过SyncGroup请求告知GroupCoordinator;
  4. 最后,GroupCoordinator会把分区方案下发给所有Consumer,各个Consumer就会跟指定Leader分区所在的Broker建立Socket连接,开始消费消息。

二、Reblance策略

当消费者组中的某个Consumer宕机或者增减分区时,GroupCoordinator会负责分区重分配,也就是所谓的 reblance 。在reblance期间,消费者组会变得 不可用 。另外,reblance可能会引发“重复消费”的问题,比如Consumer消费完某个分区中的一部分消息后还没有来得及提交offset,此时发生了reblance,然后这个分区被分配给了消费组内的另一个Consumer,这样原来被消费完的那部分消息又会被新的Consumer重新消费一遍,即发生了重复消费。

Kafka一共提供了三种Rebalance的策略: Range 、 Round-Robin 、 Sticky 。

2.1 Range策略

Range策略就是按照Partition的序号范围进行分配,也是 默认策略 。

举个例子,某个主题有8个分区:partition0-partition7。那么分区partition0-2分配给Consumer1,partition3-5给一个Consumer2,partition6-7给一个consumer3。

2.2 Round-Robin策略

Round-Robin策略,就是轮询分配。

举个例子,某个主题有8个分区:partition0-partition7。那么partiton0给Consumer1,partiton1给另一个Consumer2,依此类推……最后Consumer1分配到partiton0、3、6,Consumer2分配到partition1、4、7,Consumer3分配到partition2、5。

2.3 Sticky策略

Range策略和Round-Robin策略都存在一个问题,就是发生Rebalance的时候会导致分区被频繁重新分配。

举个例子,比如Consumer2挂掉了,那么会导致原本分配给Consumer1和Consumer3的分区也要被重新分配,这种分配很多时候是没必要的。

所以,Kafka又新增了一种 Sticky策略 ,就是说在发生Rebalance时,尽量让原本属于这个Consumer的分区不变动,再把多余的分区均匀分配出去,这样就能尽可能维持原来的分区分配策略。

  • 26
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值