Kafka-消费者-Consumer Group Rebalance设计

news2024/11/27 4:29:21

在同一个Consumer Group中,同一个Topic的不同分区会分配给不同的消费者进行消费,那么为消费者分配分区的操作是在Kafka服务端完成的吗?分区是如何进行分配呢?下面来分析Rebalance操作的原理。

方案一

Kafka最开始的解决方案是通过ZooKeeper的Watcher实现的。

每个Consumer Group在ZooKeeper下都维护了一个“/consumers/[group_id]/ids”路径,在此路径下使用临时节点记录属于此Consumer Group的消费者的Id,由Consumer启动时创建。

还有两个与ids节点同级的节点,它们分别是:
owners节点,记录了分区与消费者的对应关系;
offsets节点,记录了此Consumer Group在某个分区上的消费位置。

每个Broker、Topic以及分区在ZooKeeper中也都对应一个路径,如下所示。

  • /brokers/ids/broker_id:记录了host、port以及分配在此Broker上的Topic的分区列表。
  • /brokers/topics/[topic_name]:记录了每个Partition的Leader、ISR等信息。
  • /brokers/topics/[topic_name]/partitions/[partition_num]/state:记录了当前Leader、选举epoch等信息
    路径图如图所示。

在这里插入图片描述
每个Consumer都分别在“/consumers/[group_id]/ids”和“brokers/ids”路径上注册一个Watcher。

当“/consumers/[group_id]/ids”路径的子节点发生变化时,表示ConsumerGroup中的消费者出现了变化;

当“/brokers/ids”路径的子节点发生变化时,表示Broker出现了增减。
这样,通过Watcher,每个消费者就可以监控Consumer Group和Kafka集群的状态了。

这个方案看上去不错,但是严重依赖于ZooKeeper集群,有两个比较严重的问题:

  • 羊群效应(Herd Effect):先解释一下什么是“羊群效应”,一个被Watch的ZooKeeper节点变化,导致大量的Watcher通知需要被发送给客户端,这将导致在通知期间其他操作延迟。

    一般出现这种情况的主要原因就是没有找到客户端真正的关注点,也算是滥用Watcher的一种场景。
    继续前面的分析,任何Broker或Consumer加入或退出,都会向其余所有的Consumer发送Watcher通知触发Rebalance,就出现了“羊群效应”。

  • 脑裂(Split Brain):每个Consumer都是通过ZooKeeper中保存的这些元数据判断Consumer Group状态、Broker的状态以及Rebalance结果的,由于ZooKeeper只保证“最终一致性”,不保证“Simultaneously Consistent Cross-Client Views”,不同Consumer在同一时刻可能连接到ZooKeeper集群中不同的服务器,看到的元数据就可能不一样,这就会造成不正确的Rebalance尝试。

方案二

由于上述两个原因,Kafka的后续版本对Rebalance操作进行了改进,也对消费者进行了重新设计。

其核心设计思想是:将全部的Consumer Group分成多个子集,每个Consumer Group子集在服务端对应一个GroupCoordinator对其进行管理,GroupCoordinator是KafkaServer中用于管理Consumer Group的组件,消费者不再依赖ZooKeeper,而只有GroupCoordinator在ZooKeeper上添加Watcher。

消费者在加入或退出Consumer Group时会修改ZooKeeper中保存的元数据,这点与上文描述的方案一类似,此时会触发GroupCoordinator设置的Watcher,通知GroupCoordinator开始Rebalance操作。

下面简述这个过程:

  1. 当前消费者准备加入某Consumer Group或是GroupCoordinator发生故障转移时,消费者并不知道GroupCoordinator的网络位置,消费者会向Kafka集群中的任一Broker发送ConsumerMetadataRequest,此请求中包含了其Consumer Group的Groupld,收到请求的Broker会返回ConsumerMetadataResponse作为响应,其中包含了管理此ConsumerGroup的GroupCoordinator的相关信息。

  2. 消费者根据ConsumerMetadataResponse中的GroupCoordinator信息,连接到GroupCoordinator并周期性地发送HeartbeatRequest,HeartbeatRequest的具体格式在后面会详细介绍。

    发送HeartbeatRequest的主要作用是为了告诉GroupCoordinator此消费者正常在线,GroupCoordinator会认为长时间未发送HeartbeatRequest的消费者已经下线,触发新一轮的Rebalance操作。

  3. 如果HeartbeatResponse中带有IllegalGeneration异常,说明GroupCoordinator发起了Rebalance操作,此时消费者发送JoinGroupRequest(具体格式在后面介绍)给GroupCoordinator,JoinGroupRequest的主要目的是为了通知GroupCoordinator,当前消费者要加入指定的Consumer Group。

    之后,GroupCoordinator会根据收到的JoinGroupRequest和ZooKeeper中的元数据完成对此Consumer Group的分区分配。

  4. GroupCoordinator会在分配完成后,将分配结果写入ZooKeeper保存,并通过JoinGroupResponse返回给消费者。消费者就可以根据JoinGroupResponse中分配的分区开始消费数据。

  5. 消费者成功成为Consumer Group的成员后,会周期性发送HeartbeatRequest。如果HeartbeatResponse包含IlegalGeneration异常,则执行步骤3。如果找不到对应的GroupCoordinator(HeartbeatResponse包含NotCoordinatorForGroup异常),则周期性地执行步骤1,直至成功。

这里只是简略地描述此方案的步骤,整个方案还是有点复杂的,其中比较严谨地描述了消费者和GroupCoordinator的状态图和各个阶段可能发生的故障以及故障转移处理,本文重点关注Consumer Group Rebalance方面。

上面这种方案虽然解决了“羊群效应”、“脑裂”问题,但是还是有两个问题:

  • 分区分配的操作是在服务端的GroupCoordinator中完成的,这就要求服务端实现Partition的分配策略。当要使用新的Partition分配策略时,就必须修改服务端的代码或配置,之后重启服务,这就显得比较麻烦。

  • 不同的Rebalance策略有不同的验证需求。当需要自定义分区分配策略和验证需求时,就会很麻烦。

方案三

为了解决上述问题,Kafka进行了重新设计,将分区分配的工作放到了消费者这一端进行处理,而Consumer Group管理的工作则依然由GroupCoordinator处理。

这就让不同的模块关注不同的业务,实现了业务的切分和解耦,这种思想在设计时很重要。

重新设计后的协议在上一版本的协议上进行了修改,将JoinGroupRequest的处理过程拆分成了两个阶段,分别是Join Group阶段和Synchronizing Group State阶段。

当消费者查找到管理当前Consumer Group的GroupCoordinator后,就会进入Join Group阶段,Consumer首先向GroupCoordinator发送JoinGroupRequest请求,其中包含消费者的相关信息;

服务端的GroupCoordinator收到JoinGroupRequest后会暂存消息,收集到全部消费者之后,根据JoinGroupRequest中的信息来确定Consumer Group中可用的消费者,从中选取一个消费者成为Group Leader,还会选取使用的分区分配策略,最后将这些信息封装成JoinGroupResponse返回给消费者。

虽然每个消费者都会收到JoinGroupResponse,但是只有Group Leader收到的JoinGroupResponse中封装了所有消费者的信息。

当消费者确定自己是Group Leader后,会根据消费者的信息以及选定的分区分配策略进行分区分配。

在Synchronizing Group State阶段,每个消费者会发送SyncGroupRequest到GroupCoordinator,但是只有Group Leader的SyncGroupRequest请求包含了分区的分配结果,GroupCoordinator根据Group Leader的分区分配结果,形成SyncGroupResponse返回给所有Consumer。

消费者收到SyncGroupResponse后进行解析,即可获取分配给自身的分区。

最后,我们来了解消费者的状态转移与各请求之间的关系,如图所示。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1393162.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【文本到上下文 #2】:NLP 的数据预处理步骤

一、说明 欢迎阅读此文,NLP 爱好者!当我们继续探索自然语言处理 (NLP) 的广阔前景时,我们已经在最初的博客中探讨了它的历史、应用和挑战。今天,我们更深入地探讨 NLP 的核心——数据预处理的复杂世界。 这篇文章是我们的“完整 N…

c/c++的指针函数与函数指针

函数 定义: 函数是数学中的一个概念,它是定义在某个数集上的一个特殊的映射关系。函数将输入值(或自变量)映射到输出值(或因变量)。函数的输入和输出可以是任何类型的数据,如数字、字符串、数组…

2023年12月 C/C++(五级)真题解析#中国电子学会#全国青少年软件编程等级考试

C/C编程(1~8级)全部真题・点这里 第1题:书架 John最近买了一个书架用来存放奶牛养殖书籍,但书架很快被存满了,只剩最顶层有空余。 John共有N头奶牛(1 ≤ N ≤ 20,000),每头奶牛有自己的高度Hi(1 ≤ Hi ≤ 1…

智能安全帽定制_基于联发科MT6762平台的智能安全帽方案

智能安全帽是一种具备多项功能的高科技产品,其功能集成了视频通话监控、高清图像采集、无线数据传输、语音广播对讲、定位轨迹回放、静默报警、危险救援报警、脱帽报警、碰撞报警、近电报警以及智能调度系统等,同时还支持多功能模块的自由添加&#xff0…

7. UE5 RPG修改GAS的Attribute的值

前面几节文章介绍了如何在角色身上添加AbilitySystemComponent和AttributeSet。并且还实现了给AttributeSet添加自定义属性。接下来,实现一下如何去修改角色身上的Attribute的值。 实现拾取药瓶回血功能 首先创建一个继承于Actor的c类,actor是可以放置到…

银河麒麟操作系统 v10 中离线安装 Docker

银河麒麟操作系统 v10 中离线安装 Docker 1. 查看系统版本2. 查看 Linux 内核版本(3.10以上)3. 查看 iptabls 版本(1.4以上)4. 判断处理器架构5. 离线下载 Docker 安装包6. 移动解压出来的二进制文件到 /usr/bin 目录中7. 配置 Do…

课表排课小程序怎么制作?多少钱?

在当今的数字化时代,无论是购物、支付、点餐,还是工作、学习,都离不开各种各样的微信小程序。其中,课表排课小程序就是许多教育机构和学校必不可少的工具。那么课表排课小程序怎么制作呢?又需要多少钱呢? …

网络端口映射和端口转发的区别和联系

目 录 一、端口映射技术 1.1 原理 1.2 应用场景 1、远程访问 2、游戏主机 3、文件共享 4、监控视频共享 二、端口转发技术 2.1 原理 2.2 应用场景 1、网络负载均衡 2、网络安全 3、网络代理 三、端口映射和转发的实现方法 3.1 路由器配置 3.2 网络防火墙 …

操作系统课程设计-Linux 进程间通信

目录 前言 1 实验题目 2 实验目的 3 实验内容 3.1 步骤 3.2 关键代码 3.2.1 Server和Client的创建 3.2.2 Server核心代码 3.2.3 Server核心代码 4 实验结果与分析 5 代码 前言 本实验为课设内容,博客内容为部分报告内容,仅为大家提供参考&…

如何用Python进行数据分析(保姆级教程)

有小伙伴在学Python新手教程的时候说学Python比较复杂的地方就是资料太多了,比较复杂。 很多网上的资料都是从语法教起的,花了很多时间还是云里雾里,摸不清方向。今天就给大家来捋一捋思路!帮助大家提高学习效率! Pyt…

Docker安装开源Blog(Typecho)

前言 首先这个镜像是centos7.9进行安装PHP环境,然后挂载目录去运行的,镜像大概300MB左右,没学过PHP,没办法给Dockerfile文件 参考文章:Docker安装Typecho | D-y Blog感知不强,图一乐https://www.wlul.top…

【Mybatis】延迟加载的原理是什么?

​ 🍎个人博客:个人主页 🏆个人专栏:Mybatis ⛳️ 功不唐捐,玉汝于成 ​ 目录 前言 正文 MyBatis实现延迟加载的步骤: 生成代理对象: 触发时机: 执行查询: 填…

《169. 多数元素》C语言题解(力扣)(OJ题)

题目链接:169. 多数元素 - 力扣(LeetCode) 个人博客主页:https://blog.csdn.net/2301_79293429?typeblog 专栏:https://blog.csdn.net/2301_79293429/category_12545690.html 个人力扣题解主页:我的题解…

K8s-架构

一、K8s节点划分 K8s集群包含Master(控制节点)和Node(工作节点),应用部署在Node节点上。 集群架构图: 二、Master节点 Master节点分成四个组件:scheduler、ApiServer、Controller Manager、ETCD。类似三层结构,controller&#…

[自动化分布式] Zabbix自动发现与自动注册

abbix 自动发现(对于 agent2 是被动模式) zabbix server 主动的去发现所有的客户端,然后将客户端的信息登记在服务端上。 缺点是如果定义的网段中的主机数量多,zabbix server 登记耗时较久,且压力会较大 部署 添加zabb…

Firefox 100 正式发布

五月三日,Firefox发布了它的第100个版本,来回顾一下Firefox是如何走到今天这一步的,以及在第100个版本中发布了哪些功能。 回顾 2004年,《纽约时报》上宣布了Firefox 1.0的发布,这个广告列出了为第一版做出贡献的每一…

【MATLAB源码-第115期】基于matlab的QSM正交空间调制系统仿真,输出误码率曲线。

操作环境: MATLAB 2022a 1、算法描述 正交空间调制(QSM)是一种先进的无线通信技术,它通过利用发射端的多天线阵列来传输信息,从而提高了数据传输的效率和速率。这种技术的关键在于它使用天线阵列的空间特性来编码额…

机器学习笔记——机器学习的分类

1 机器学习是啥 机器学习是人工智能的一个分支,它是一门研究机器获取新知识和新技能,并识别现有知识的学问。 机器学习已广泛应用于数据挖掘、计算机视觉、自然语言处理、生物特征识别、搜索引擎、医学诊断、检测信用卡欺诈、证券市场分析、DNA 序列测…

交换机配置及网络测试

实验环境 拓扑图 Ip规划表 部门 主机数量 网络地址 子网掩码 网关 可用ip Vlan 市场部 38 192.168.131.0 255.255.255.0 192.168.131.1 2-254 11 研发部 53 192.168.132.0 255.255.255.0 192.168.132.1 2-254 12 财务部 9 192.168.133.0 255.255.255…

Chatopera 云服务支持大语言模型对话(LLM),定制您的聊天机器人

2024 年,Chatopera 云服务继续不断完善,为开发者提供最好的定制聊天机器人的工具。在过去的一年,用户们反映最多的建议是 Chatopera 云服务内置大语言模型的对话,今天 Chatopera 云服务完成了产品升级,满足了这个诉求。…