Kafka设计原理详解
Kafka核心总控制器 (Controller)
在Kafka集群中,通常会有一个或多个broker,其中一个会被选举为控制器 (Kafka Controller),其主要职责是管理整个集群中所有分区和副本的状态。具体来说:
- 当某个分区的leader副本出现故障时,控制器负责选举新的leader副本。
- 当探测到某个分区的ISR集合发生变化时,控制器负责通知所有broker更新其元数据信息。
- 当使用kafka-topics.sh脚本为某个topic增加分区数量时,同样由控制器负责确保新分区被其他节点感知到。
Controller选举机制
Kafka集群在启动时会自动选举一台broker作为控制器,该选举过程的关键在于每个broker都尝试在Zookeeper上创建一个临时节点/controller
,而Zookeeper会确保只有一个broker能够成功创建此节点,成为集群的控制器。如果当前的控制器宕机,其临时节点将消失,其他broker将监听该节点的变化,一旦发现节点消失,它们将再次竞选成为新的控制器,这便构成了控制器的选举机制。
控制器角色的broker需要承担一些额外的职责,包括:
- 监听与broker相关的变化,通过为Zookeeper中的
/brokers/ids/
节点添加BrokerChangeListener来处理broker的增减变化。 - 监听与topic相关的变化,通过为Zookeeper中的
/brokers/topics
节点添加TopicChangeListener来处理topic的增减变化,同时为/admin/delete_topics
节点添加TopicDeletionListener以处理删除topic的操作。 - 从Zookeeper中读取并管理与topic、partition以及broker有关的所有信息,通过为所有topic对应的
/brokers/topics/[topic]
节点添加PartitionModificationsListener来监听topic中分区分配的变化。 - 更新集群的元数据信息,并将其同步到其他普通的broker节点中。
Partition副本选举Leader机制
当控制器检测到某个分区的leader所在的broker宕机时,它会从ISR列表中选择第一个可用的broker作为新的leader,前提是参数unclean.leader.election.enable
设置为false
,这意味着只有在ISR列表中的副本之间进行选举。如果unclean.leader.election.enable
设置为true
,则表示在ISR列表中的所有副本都宕机时,也可以从ISR列表之外的副本中选择新的leader,这种设置可以提高可用性,但可能导致新leader的数据同步滞后。副本进入ISR列表需要满足以下两个条件:
- 副本节点不能产生分区,必须能够与Zookeeper保持会话并与leader副本保持网络连接。
- 副本必须能够复制leader上的所有写操作,并且不能滞后太多。滞后时间由
replica.lag.time.max.ms
配置决定,超过此时间没有与leader同步的副本将被移出ISR列表。
消费者消费消息的offset记录机制
每个消费者定期将其消费分区的offset提交到名为__consumer_offsets
的Kafka内部主题。提交时,使用key表示consumerGroupId + topic + 分区号,value表示当前的offset值。Kafka会定期清理__consumer_offsets
主题中的消息,保留最新的offset记录。由于__consumer_offsets
可能会受到高并发请求的影响,Kafka默认将其分配了50个分区(可以通过offsets.topic.num.partitions
进行配置),以增加其并发处理能力。
消费者Rebalance机制
Rebalance指的是在消费组中的消费者数量发生变化或者消费的分区数发生变化时,Kafka会重新分配消费者与分区的关系。例如,如果消费组中的某个消费者崩溃,Kafka会自动将分配给它的分区重新分配给其他消费者,如果该消费者重新启动,则会再次接收到一些分区。需要注意的是,Rebalance仅适用于使用subscribe方式消费的情况,而不适用于使用assign方式手动指定分区的情况。
触发消费者Rebalance的情况包括:
- 消费组中的消费者数量发生变化。
- 动态增加了topic的分区。
- 消费组订阅了更多的topic。
在Rebalance过程中,消费者无法从Kafka消费消息,这可能会对Kafka的吞吐量产生影响,特别是在包含大量节点的Kafka集群中,Rebalance可能会耗费较长时间,因此应尽量避免在系统高峰期进行Rebalance操作。
Rebalance的过程可以概括如下:
当有新的消费者加入消费组时,消费者、消费组和组协调器之间会经历以下几个阶段。
第一阶段:选择组协调器(Selecting the Group Coordinator)
在消费者组(Consumer Group)中,每个消费者组会选择一个代表自己的组协调器(Group Coordinator)。这个组协调器的主要职责是监控该消费组内所有消费者的心跳,检测宕机情况,并启动消费者再平衡(Consumer Rebalance)。
每个消费者在启动时都会向 Kafka 集群的某个节点发送 FindCoordinatorRequest 请求,以查找与其对应的组协调器(Group Coordinator),然后建立与该协调器的网络连接。
组协调器的选择方式遵循以下公式:hash(consumer group id) % _consumer_offsets 主题的分区数。其中,分区的 leader 代表着该消费者组的协调器。
第二阶段:加入消费组(Joining the Consumer Group)
一旦成功找到了消费者组对应的 Group Coordinator,消费者将进入加入消费组的阶段。在这个阶段,消费者会向 Group Coordinator 发送 JoinGroupRequest 请求,并等待响应。然后,Group Coordinator 从消费者组中选择第一个加入的消费者作为组的领袖(Consumer Group Coordinator),并将消费者组的信息发送给领袖。
第三阶段:同步消费组(Sync Group)
消费者领袖通过向 Group Coordinator 发送 SyncGroupRequest 来同步消费组的状态。随后,Group Coordinator 将分区分配方案下发给各个消费者,消费者将根据指定的分区 leader broker 进行网络连接和消息消费。
消费者再平衡的分区分配策略
消费者再平衡有三种主要策略:range(范围)、round-robin(轮询)和sticky(粘性)。Kafka 提供了消费者客户端参数 partition.assignment.strategy 来设置消费者与订阅主题之间的分区分配策略,默认情况下是使用 range 分配策略。
以一个主题具有 10 个分区(0-9)和三个消费者为例,不同策略的分配如下:
-
Range 策略:按照分区序号排序,前 1 个消费者分配 4 个分区,后 2 个消费者分配 3 个分区。
- 消费者 1:分区 0-3
- 消费者 2:分区 4-6
- 消费者 3:分区 7-9
-
Round-robin 策略:轮流分配分区,每个消费者分到不同的分区。
- 消费者 1:分区 0, 3, 6, 9
- 消费者 2:分区 1, 4, 7
- 消费者 3:分区 2, 5, 8
-
Sticky 策略:初始时类似于 round-robin,但在再平衡时,需要确保两个原则:
- 分区分配尽可能均匀。
- 分区分配尽可能与上次分配相同。 当两者发生冲突时,第一个原则优先考虑。例如,如果第三个消费者挂掉,重新分配后的结果如下:
- 消费者 1:分区 0-3, 7
- 消费者 2:分区 4-6, 8, 9
生产者发布消息机制剖析
-
写入方式:生产者采用推送(push)模式将消息发布到 Kafka Broker。每条消息都被附加到相应的分区,从而实现顺序写入磁盘。这种顺序写入方式提高了 Kafka 的吞吐量,因为与随机写入内存相比,顺序写入磁盘更加高效。
-
消息路由:当生产者发送消息到 Broker 时,会根据分区算法选择将消息存储到哪个分区。路由机制如下:
- 如果指定了分区,则直接使用指定的分区。
- 如果未指定分区但指定了键(key),则根据键的值进行哈希计算,以选出一个分区。
- 如果既未指定分区也未指定键,则使用轮询方式选出一个分区。
这些步骤组成了 Kafka 生产者的消息发布流程。
Kafka 消息写入和高水位(HW)详解
Kafka 中消息的写入和高水位(High Watermark,简称 HW)有关重要步骤,这些步骤如下:
-
生产者查找分区 leader: 生产者首先从 Zookeeper 的"/brokers/.../state"节点中找到该分区的 leader。
-
生产者向 leader 发送消息: 生产者将要发送的消息发送给分区的 leader。
-
Leader 写入消息到本地日志: 分区的 leader 将接收到的消息写入自己的本地日志。
-
Followers 从 Leader 拉取消息: 非 leader 的 followers 从分区的 leader 拉取消息,并将这些消息写入自己的本地日志。随后,followers 向 leader 发送确认 ACK。
-
Leader 收到所有 ISR 中的 Replica 的 ACK: Leader 收到来自 ISR(In-Sync Replicas,同步副本)中所有副本的确认 ACK 后,将高水位(HW,即最后 commit 的 offset)增加,并向生产者发送 ACK。
高水位(HW)和日志末尾偏移(LEO)详解
高水位(HW)通常用于限制消费者的读取位置。在 Kafka 中,HW 是 ISR 中最小的 LEO(Log-End-Offset)的值。消费者最多只能消费到 HW 所在的位置。每个 Replica(副本)都维护自己的 HW 状态,包括 Leader 和 Followers。Leader 负责等待消息被 ISR 中的所有副本同步后,才会更新 HW。这确保了消息不会在被生产后立即被消费,而是要等待所有 ISR 中的副本都同步成功后才能被消费。这种机制保证了即使 Leader 所在的 Broker 失效,消息仍然可以从新选举的 Leader 中获取。
对于来自内部 Broker 的读取请求,通常不会受到 HW 的限制,因为这些请求是针对 Kafka 内部的,而不需要考虑消费者的限制。HW 主要用于外部消费者,以确保它们不会读取到未同步的消息。
结合HW 和LEO看下 acks=1的情况
日志分段存储
Kafka一个分区的消息数据对应存储在一个文件夹下,以topic名称+分区号命名,消息在分区内是分段(segment)存储, 每个段的消息都存储在不一样的log文件里,这种特性方便old segment file快速被删除,kafka规定了一个段位的 log 文 件最大为1G, 做这个限制目的是为了方便把 log 文件加载到内存去操作:
这个9936472之类的数字,就是代表了这个日志段文件里包含的起始 Offset, 也就说明这个分区里至少都写入了接近 1000万条数据了。
Kafka Broker 有一个参数,log.segment.bytes,限定了每个日志段文件的大小,最大就是1GB。
一个日志段文件满了,就自动开一个新的日志段文件来写入,避免单个文件过大,影响文件的读写性能,这个过程叫做
log rolling, 正 在 被 写 入 的 那 个 日 志 段 文 件 , 叫 做 active log segment。
最后附一张zookeeper 节点数据图:
相关文章:

Kafka设计原理详解
Kafka核心总控制器 (Controller) 在Kafka集群中,通常会有一个或多个broker,其中一个会被选举为控制器 (Kafka Controller),其主要职责是管理整个集群中所有分区和副本的状态。具体来说: 当某个分区的leader副本出现故障时&#…...

光耦继电器
光耦继电器(光电继电器) AQW282SX 282SZ 280SX 280SZ 284SX 284SZ 212S 212SX 21 2SZ 文章目录 光耦继电器(光电继电器)前言一、光耦继电器是什么二、光耦继电器的类型三、光电耦合器的应用总结前言 光耦继电器在工业控制、通讯、医疗设备、家电及汽车电子等领域得到广泛应…...

【C++练级之路】【Lv.5】动态内存管理(都2023年了,不会有人还不知道new吧?)
目录 一、C/C内存分布二、new和delete的使用方式2.1 C语言内存管理2.2 C内存管理2.2.1 new和delete操作内置类型2.2.2 new和delete操作自定义类型 三、new和delete的底层原理3.1 operator new与operator delete函数3.2 原理总结3.2.1 内置类型3.2.2 自定义类型 四、定位new表达…...

2016年第五届数学建模国际赛小美赛A题臭氧消耗预测解题全过程文档及程序
2016年第五届数学建模国际赛小美赛 A题 臭氧消耗预测 原题再现: 臭氧消耗包括自1970年代后期以来观察到的若干现象:地球平流层(臭氧层)臭氧总量稳步下降,以及地球极地附近平流层臭氧(称为臭氧空洞&#x…...

springMVC-与spring整合
一、基本介绍 在项目开发中,spring管理的 Service和 Respository,SrpingMVC管理 Controller和ControllerAdvice,分工明确 当我们同时配置application.xml, springDispatcherServlet-servlet.xml , 那么注解的对象会被创建两次, 故…...

【二叉树】【单调双向队列】LeetCode239:滑动窗口最大值
作者推荐 map|动态规划|单调栈|LeetCode975:奇偶跳 涉及知识点 单调双向队列 二叉树 题目 给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。 返回 滑动…...

如何使用树莓派Bookworm系统中配置网络的新方法NetworkManager
树莓派在 10 月新出的 Bookworm 版本系统中,将使用多年的 dhcpcd 换成了 NetworkManager(以前是在rasp-config中可选),这是因为 Raspberry Pi OS 使用的是 Debian 内核(和 Ubuntu 一样),所以树莓…...

恶意软件分析沙箱在网络安全策略中处于什么位置?
恶意软件分析沙箱提供了一种全面的恶意软件分析方法,包括静态和动态技术。这种全面的评估可以更全面地了解恶意软件的功能和潜在影响。然而,许多组织在确定在其安全基础设施中实施沙箱的最有效方法方面面临挑战。让我们看一下可以有效利用沙盒解决方案的…...

ARM学习(24)Can的高阶认识和错误处理
笔者来聊一下CAN协议帧的认识和错误处理。 1、CAN协议帧认识 CAN 差分信号,是经过CAN收发器转成差分信号的,CAN RX和TX是逻辑电平。CAN的基础知识,可参考笔者这边文章:ARM学习(21)STM32 外设Can的认识与驱…...

网络通信--深入理解网络和TCP / IP协议
计算机网络体系结构 TCP/IP协议族 TCP / IP 网络传输中的数据术语 网络通信中的地址和端口 window端查看IP地址和MAC地址:ipconfig -all MAC层地址是在数据链路层的;IP工作在网络层的 MAC是48个字节,IP是32个字节 在子网(局域…...

IPC之九:使用UNIX Domain Socket进行进程间通信的实例
socket 编程是一种用于网络通信的编程方式,在 socket 的协议族中除了常用的 AF_INET、AF_RAW、AF_NETLINK等以外,还有一个专门用于 IPC 的协议族 AF_UNIX,IPC 是 Linux 编程中一个重要的概念,常用的 IPC 方式有管道、消息队列、共…...

学习在UE中通过Omniverse实现对USD文件的Live-Sync(实时同步编辑)
目标 前一篇 学习了Omniverse的一些基础概念。本篇在了解这些概念的基础上,我想体验下Omniverse的一些具体的能力,特别是 Live-Sync (实时同步) 相关的能力。 本篇实践了使用Omniverse的力量在UE中建立USD文件的 Live-Sync 编辑。由于相关的知识我是从…...

实现打印一个数字金字塔。例如:输入5,图形如下图所示
1*12**123***1234**** 12345*****#include<stdio.h> void main() {int i,j,l,n,k;scanf("%d",&n);/**********Program**********//********** End **********/ } 当我们拿到这个题目的时候可以看见题目给了我们五个变量,其中n是我们输入的数…...
hive sql常用函数
目录 一、数据类型 二、基础运算 三、字符串函数 1、字符串长度函数: length() 2、字符串反转函数:reverse 3、字符串连接函数 4、字符串截取函数 5、字符串分割函数:split 6、字符串查找函数 7、ascii 8、base64 9、character_length 10、c…...
Spark系列之:使用spark合并hive数据库多个分区的数据到一个分区中
Spark系列之:使用spark合并hive数据库多个分区的数据到一个分区中 把两个分区的数据合并到同一个分区下把其中一个分区的数据通过append方式添加到另一个分区即可 %spark val df spark.sql("select * from optics_prod.product_1h_a where datetime202311142…...
《重构-改善既有代
重要列表 1、如果你发现自己需要为程序添加一个特性,而代码结构使你无法很方便地达成目的,那就先重构哪个程序,使特性的添加比较容易的进行,然后再添加特性 2、重构前,先检查自己是否有一套可靠的测试机制࿰…...

vue3(七)-基础入门之事件总线与动态组件
一、事件总线 事件总线使用场景: 两个兄弟组件之间的传参,或者两个没有关联的组件之间的传参 html :引入 publicmsg 与 acceptmsg 自定义组件 (自定义组件名称必须小写) <body><div id"app"><publicmsg></…...

【计算机网络】网络层——IP协议
目录 一. 基本概念 二. 协议报文格式 三. 网段划分 1. 第一次划分 2. CIDR方案 3. 特殊的IP地址 四. IP地址不足 1. 私有IP和公网IP 2. DHCP协议 3. 路由器 4. NAT技术 内网穿透(NAT穿透) 五. 路由转发 路由表生成算法 结束语 一. 基本概念 IP指网络互连协议…...

《钢结构设计标准》中抗震性能化设计的概念
文章目录 0. 背景1. 前言2. 什么是抗震性能化设计3. 我国规范是如何实现性能化设计的4. 从能量角度理解性能化设计05. 《钢结构设计标准》抗震性能化设计的思路06. 《钢结构设计标准》抗震性能化设计的步骤 0. 背景 关于抗震性能化设计,之前一直理解的很模糊&#…...
【算法】【动规】回文串系列问题
文章目录 跳转汇总链接3.1 回文子串3.2 最长回文子串3.3 分割回文串 IV3.4 分割回文串II(hard) 跳转汇总链接 👉🔗动态规划算法汇总链接 3.1 回文子串 🔗题目链接 给定一个字符串 s ,请计算这个字符串中有多少个回文子字符串。 …...

css实现圆环展示百分比,根据值动态展示所占比例
代码如下 <view class""><view class"circle-chart"><view v-if"!!num" class"pie-item" :style"{background: conic-gradient(var(--one-color) 0%,#E9E6F1 ${num}%),}"></view><view v-else …...

Java-41 深入浅出 Spring - 声明式事务的支持 事务配置 XML模式 XML+注解模式
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...
在Ubuntu中设置开机自动运行(sudo)指令的指南
在Ubuntu系统中,有时需要在系统启动时自动执行某些命令,特别是需要 sudo权限的指令。为了实现这一功能,可以使用多种方法,包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法,并提供…...
人工智能--安全大模型训练计划:基于Fine-tuning + LLM Agent
安全大模型训练计划:基于Fine-tuning LLM Agent 1. 构建高质量安全数据集 目标:为安全大模型创建高质量、去偏、符合伦理的训练数据集,涵盖安全相关任务(如有害内容检测、隐私保护、道德推理等)。 1.1 数据收集 描…...
鸿蒙(HarmonyOS5)实现跳一跳小游戏
下面我将介绍如何使用鸿蒙的ArkUI框架,实现一个简单的跳一跳小游戏。 1. 项目结构 src/main/ets/ ├── MainAbility │ ├── pages │ │ ├── Index.ets // 主页面 │ │ └── GamePage.ets // 游戏页面 │ └── model │ …...

五子棋测试用例
一.项目背景 1.1 项目简介 传统棋类文化的推广 五子棋是一种古老的棋类游戏,有着深厚的文化底蕴。通过将五子棋制作成网页游戏,可以让更多的人了解和接触到这一传统棋类文化。无论是国内还是国外的玩家,都可以通过网页五子棋感受到东方棋类…...

使用SSE解决获取状态不一致问题
使用SSE解决获取状态不一致问题 1. 问题描述2. SSE介绍2.1 SSE 的工作原理2.2 SSE 的事件格式规范2.3 SSE与其他技术对比2.4 SSE 的优缺点 3. 实战代码 1. 问题描述 目前做的一个功能是上传多个文件,这个上传文件是整体功能的一部分,文件在上传的过程中…...
算法刷题-回溯
今天给大家分享的还是一道关于dfs回溯的问题,对于这类问题大家还是要多刷和总结,总体难度还是偏大。 对于回溯问题有几个关键点: 1.首先对于这类回溯可以节点可以随机选择的问题,要做mian函数中循环调用dfs(i&#x…...
STL 2迭代器
文章目录 1.迭代器2.输入迭代器3.输出迭代器1.插入迭代器 4.前向迭代器5.双向迭代器6.随机访问迭代器7.不同容器返回的迭代器类型1.输入 / 输出迭代器2.前向迭代器3.双向迭代器4.随机访问迭代器5.特殊迭代器适配器6.为什么 unordered_set 只提供前向迭代器? 1.迭代器…...

Pandas 可视化集成:数据科学家的高效绘图指南
为什么选择 Pandas 进行数据可视化? 在数据科学和分析领域,可视化是理解数据、发现模式和传达见解的关键步骤。Python 生态系统提供了多种可视化工具,如 Matplotlib、Seaborn、Plotly 等,但 Pandas 内置的可视化功能因其与数据结…...