Kafka之存储设计
文章目录
- 1. 分区和副本的存储结构
- 1. 分区和副本的分布
- 2. 存储目录结构
- 3. 文件描述
- 2. 相关配置
- 3. 数据文件类型
- 4. 数据定位原理
- LogSegment 类
- UnifiedLog 类
- 5. 副本数据同步
- HW水位线
- LEO末端偏移量
- HW更新原理
- 6. 数据清除
1. 分区和副本的存储结构
在一个多 broker 的 Kafka 集群中,topic 的分区和副本在各个 broker 上的存储文件夹分布如下:
假设有以下设置:
- 一个 Kafka 集群包含 3 个 broker(broker 0, broker 1, broker 2)。
- 一个 topic
my-topic
,有 3 个分区(partition 0, partition 1, partition 2)。 - 每个分区有 2 个副本。
1. 分区和副本的分布
Kafka 会在多个 broker 之间分配分区和副本。假设分配如下:
partition 0
:- leader: broker 0
- follower: broker 1
partition 1
:- leader: broker 1
- follower: broker 2
partition 2
:- leader: broker 2
- follower: broker 0
2. 存储目录结构
每个 broker 的数据目录结构如下(假设 log.dirs
配置为 /var/lib/kafka/data
):
- Broker 0 (
/var/lib/kafka/data
)
/var/lib/kafka/data
└── my-topic-0 # partition 0 leader├── 00000000000000000000.log├── 00000000000000000000.index├── 00000000000000000000.timeindex
└── my-topic-2 # partition 2 follower├── 00000000000000000000.log├── 00000000000000000000.index├── 00000000000000000000.timeindex
- Broker 1 (
/var/lib/kafka/data
)
/var/lib/kafka/data
└── my-topic-0 # partition 0 follower├── 00000000000000000000.log├── 00000000000000000000.index├── 00000000000000000000.timeindex
└── my-topic-1 # partition 1 leader├── 00000000000000000000.log├── 00000000000000000000.index├── 00000000000000000000.timeindex
- Broker 2 (
/var/lib/kafka/data
)
/var/lib/kafka/data
└── my-topic-1 # partition 1 follower├── 00000000000000000000.log├── 00000000000000000000.index├── 00000000000000000000.timeindex
└── my-topic-2 # partition 2 leader├── 00000000000000000000.log├── 00000000000000000000.index├── 00000000000000000000.timeindex
3. 文件描述
每个分区目录包含多个文件:
.log
文件:存储实际的消息数据。.index
文件:存储消息偏移量索引,以便快速定位消息。.timeindex
文件:存储消息时间戳索引,以便基于时间进行查找。
2. 相关配置
在 Apache Kafka 中,消息到达 leader broker 后,实际上是先写入操作系统的页缓存,然后由操作系统决定何时将数据刷入磁盘。
Kafka 允许通过配置参数来控制消息何时刷入磁盘。主要有以下几个重要的参数:
log.flush.interval.messages
:指定在写入多少条消息后,强制将数据刷入磁盘。默认为Long.MAX_VALUE
,即不基于消息数量进行刷盘。log.flush.interval.ms
:指定时间间隔(以毫秒为单位),强制将数据刷入磁盘。默认为Long.MAX_VALUE
,即不基于时间进行刷盘。log.flush.scheduler.interval.ms
:默认值为3000
毫秒。这只是一个检查的频率,实际的刷盘行为是由log.flush.interval.ms
决定的。当调度器检查时,如果发现已经超过了log.flush.interval.ms
设置的时间间隔,就会触发刷盘操作。log.segment.bytes
:控制单个日志段文件的最大大小,当一个日志段文件达到指定大小时,Kafka 会创建一个新的日志段文件,默认值1G。log.segment.delete.delay.ms
:控制日志段文件在被删除之前的延迟时间。当一个日志段文件被标记为删除后,Kafka 会等待指定的延迟时间才会真正删除该文件。这为潜在的恢复操作提供了缓冲时间。默认值60000 ms。log.roll.ms
和log.roll.hours
:控制日志段文件的滚动时间间隔,无论日志段文件的大小如何,当达到指定的时间间隔时,Kafka 会创建一个新的日志段文件。log.roll.hours
默认值168 小时(7 天)。
3. 数据文件类型
-
.index 文件:
- 描述:这是 Kafka 的偏移量索引文件。它用于快速查找消息在日志文件中的位置。
- 命名格式:
00000000000000000000.index
- 作用:通过这个索引文件,Kafka 可以快速定位消息在日志文件中的物理位置,以便更快地读取消息。
-
.log 文件:
- 描述:这是 Kafka 的日志文件,存储实际的消息数据。
- 命名格式:
00000000000000000000.log
- 作用:包含了生产者发送的消息内容。每个日志文件是一个分区的一部分,日志文件的命名表示消息的起始偏移量。
-
.timeindex 文件:
- 描述:这是 Kafka 的时间戳索引文件,存储消息的时间戳索引。
- 命名格式:
00000000000000000000.timeindex
- 作用:通过这个文件,Kafka 可以根据时间戳快速查找消息。这个文件对于实现基于时间的消息查找非常重要。
-
.snapshot 文件:
- 描述:这是 Kafka 的快照文件,记录了日志段的元数据快照。
- 命名格式:
00000000000000000016.snapshot
- 作用:用于恢复日志段的元数据,保证在崩溃恢复时能够正确地重建索引和时间戳数据。
-
leader-epoch-checkpoint 文件:
- 描述:这是 Kafka 用于记录 leader 选举周期的检查点文件。
- 作用:记录了分区的 leader 副本在不同的选举周期中的偏移量信息,帮助 Kafka 在故障恢复时确定正确的 leader 和消息偏移量。
-
partition.metadata 文件:
- 描述:这是 Kafka 的分区元数据文件。
- 作用:存储分区的基本元数据信息,如分区的 leader、replica 列表等,用于分区的管理和协调。
4. 数据定位原理
log等文件直接打开会乱码,使用以下工具可以解析到控制台。
kafka-run-class.sh kafka.tools.DumpLogSegments --files /path/to/log-file.log --print-data-log
一个log文件里面有如下内容,
Kafka 日志文件中的内容并不是简单的按行排列的消息,而是采用了批处理(batch)的方式来存储消息。
那么.index文件中可能是如下内容:
offset: 3 position: 95
.index
文件并不会为每一条消息都记录映射关系,而是每隔一定的字节数(由配置 log.index.interval.bytes
决定,默认4096)记录一次。
如上图,
LogSegment 类
LogSegment
主要负责一个段的日志管理。它包括:
- 日志文件(.log):存储实际的消息数据。
- 偏移量索引文件(.index):存储消息偏移量到物理位置的映射。
- 时间戳索引文件(.timeindex):存储消息时间戳到物理位置的映射。
UnifiedLog 类
UnifiedLog
管理一个分区的所有日志段。它通过跳表(ConcurrentSkipListMap
)实现多个 LogSegment
日志的连续存储。UnifiedLog
的主要职责包括:
- 消息写入:将消息追加到当前活动的
LogSegment
中。如果当前日志段已满,滚动到新的日志段。 - 消息读取:根据偏移量或时间戳查找并读取消息,可能跨越多个日志段。
- 日志截断:根据保留策略(如日志保留时间或大小),截断过期或不需要的日志段。
- 数据恢复:在 broker 重启或故障恢复时,从日志段中恢复数据。
如图,要查询偏移量为7的数据:
-
通过跳表定位到对应的LogSegment
-
通过.index,经由二分法等高效定位指定偏移量的位置(如果没记录,则使用最大的小于偏移量位置)
-
按照指定位置快速定位到偏移量7的位置(或更前面一些)
5. 副本数据同步
follower会定时向leader拉取数据。
HW水位线
水位线(HW)是 Kafka 中每个分区的一个偏移量,它表示已经被所有同步副本(leader 和 follower)确认并复制的最高偏移量。
-
数据一致性:HW 确保只有那些已经被所有同步副本成功复制的消息才会对消费者可见。这样可以防止数据不一致的问题,防止读取到未被完全复制的消息。
-
数据可靠性:HW 确保了在系统发生故障时,数据不会丢失,并且消费者读取到的数据是可靠的。如果设置了
acks=all
,那么只有当所有同步副本都确认收到消息后,HW 才会更新。这确保了数据已经被多个副本存储,防止数据丢失。 -
故障恢复:当 leader 副本故障时,Kafka 会从同步副本中选举一个新的 leader 副本。新的 leader 会从 HW 位置开始,确保它拥有所有已提交的消息。
-
提高数据处理的可靠性和简化系统设计。生产者和消费者不需要处理复杂的数据一致性逻辑,只需依赖 Kafka 的 HW 机制。消费者读取的数据都是已经被确认的可靠数据,避免处理未确认数据带来的复杂性和错误。
LEO末端偏移量
LEO(Log End Offset)是 Kafka 中的一个重要概念,代表一个分区的日志末端偏移量。具体来说,LEO 是指分区中下一条待写入消息的偏移量。
HW更新原理
Leader会记录所有副本的LEO,以及HW。
Follower会记录自己的LEO,以及HW。
-
消息来到Leader,Leader更新自身LEO。
-
Follower向Leader同步数据,同步发送自身LEO,Leader更新LEO数据,并更新HW。
-
Leader将数据返回到Follower,并携带HW,Followe同步HW的值,并更新自身LEO。
如此反复,LEO和HW就在不断地更新。
6. 数据清除
log.retention.hours
,log.retention.minutes
,log.retention.ms
:日志保留的时间。超过这个时间的日志文件将被删除。log.retention.hours
默认值为168(即 7 天)log.retention.check.interval.ms
:指定 Kafka Broker 多长时间检查一次日志文件,并根据配置的日志保留策略删除或压缩过期的日志文件。默认值:300000 毫秒(即 5 分钟).log.retention.bytes
:每个分区保留的最大日志大小,超过这个大小的日志将被删除。默认值:-1(表示没有大小限制)。log.cleanup.policy
:日志清理策略,支持 delete 和 compact 两种模式。delete 模式表示根据保留策略删除旧日志,compact 模式表示日志压缩。默认值为delete。- log.cleaner.min.cleanable.ratio:日志分段中可以被清理的最小比例。仅当分段中可清理的日志比例超过此值时,才会触发日志压缩。
- log.cleaner.delete.retention.ms:被标记为删除的记录在清理前的保留时间(以毫秒为单位)。在此时间之后,记录将从日志中永久删除。
关于 log.cleanup.policy=compact
,因为数据会丢失,所以这种策略只适用于保存数据最新状态的特殊场景。压缩步骤如下:
-
标记旧数据:
Kafka会通过定期扫描日志分段(log segment)来查找每个key的最新值。对于同一个key,Kafka会将旧的值标记为删除(通常是通过在记录上设置一个删除标记)。 -
合并过程:
Kafka在后台运行一个合并过程(compaction process),这个过程会将分段中旧的key值对删除,保留最新的key值对。合并过程是增量进行的,Kafka并不会在每次写入消息时都触发这个过程。 -
实际删除:
被标记为删除的key值对并不会立即从日志分段中删除。Kafka的压缩过程是定期进行的,时间间隔和触发条件可以通过配置参数来调整。默认情况下,Kafka会在后台线程中异步执行这个压缩过程。
相关文章:

Kafka之存储设计
文章目录 1. 分区和副本的存储结构1. 分区和副本的分布2. 存储目录结构3. 文件描述 2. 相关配置3. 数据文件类型4. 数据定位原理LogSegment 类UnifiedLog 类 5. 副本数据同步HW水位线LEO末端偏移量HW更新原理 6. 数据清除 1. 分区和副本的存储结构 在一个多 broker 的 Kafka 集…...
Python面试整理-Python中的函数定义和调用
在Python中,函数是一种封装代码的方式,使得代码模块化和复用性更强。定义和调用函数是Python编程中的基本技能。以下是关于如何在Python中定义和调用函数的详细介绍: 函数定义 函数在Python中使用def关键字进行定义。函数体开始前,通常有一个可选的文档字符串(docstring)…...

HTTP协议、Wireshark抓包工具、json解析、天气爬虫
HTTP超文本传输协议 HTTP(Hyper Text Transfer Protocol): 全称超文本传输协议,是用于从万维网(WWW:World Wide Web )服务器传输超文本到本地浏览器的传送协议。 HTTP 协议的重要特点: 一发一收…...

electron项目中实现视频下载保存到本地
第一种方式:用户自定义选择下载地址位置 渲染进程 // 渲染进程// 引入 import { ipcRenderer } from "electron";// 列表行数据下载视频操作,diffVideoUrl 是视频请求地址 handleDownloadClick(row) {if (!row.diffVideoUrl) {this.$message…...

基于chrome插件的企业应用
一、chrome插件技术介绍 1、chrome插件组件介绍 名称 职责 访问权限 DOM访问情况 popup 弹窗页面。即打开形式是通过点击在浏览器右上方的icon,一个弹窗的形式。 注: 展示维度 browser_action:所有页面 page_action:指定页面 可访问绝大部分api 不可以 bac…...

unittest框架和pytest框架区别及示例
unittest框架和pytest框架区别及示例 类型unittest框架pytest框架unittest框架示例pytest框架示例安装python内置的一个单元测试框架,标准库,不需要安装第三方单元测试库,需要安装使用时直接引用 import unittest安装命令:pip3 install pyte…...
IDEA性能优化方法解决卡顿
文章目录 前言一、可以采取以下措施:二、VM Options的参数解释1. 内存设置2. 性能调优3. GC(垃圾回收)调优4. 调试和诊断5. 其它设置6.设置 VM Options 的步骤: 总结 前言 我们在使用 IntelliJ IDEA的时候有时候会觉得卡顿&#x…...
Mysql集合转多行
mysql 集合转多行 SELECT substring_index(substring_index(t1.group_ids, ,, n), ,, -1) AS group_id FROM (select 908,909 as group_ids ) t1, (SELECT rownum : rownum 1 AS n FROM ( SELECT rownum : 0 ) r, orders ) t2 WHERE n < ( LENGTH( t1.group_ids ) - LENGT…...
MFC:只允许产生一个应用程序实例的具体实现
在MFC(Microsoft Foundation Class)应用程序中,如果你想限制只允许产生一个应用程序实例,通常会使用互斥体(Mutex)来实现。这可以确保如果用户尝试启动第二个实例时,它会被阻止或将焦点返回到已…...
深入理解TCP/IP协议中的三次握手
👍 个人网站:【洛秋资源小站】 深入理解TCP/IP协议中的三次握手 在计算机网络中,TCP/IP协议是通信的基石。理解TCP/IP协议中的三次握手是掌握网络通信的关键步骤之一。本文将详细解释TCP/IP协议中的三次握手过程,探讨其工作原理&…...
【React】事件绑定、React组件、useState、基础样式
React 教程 目录 事件绑定 1.1. 基础实现 1.2. 使用事件参数 1.3. 传递自定义参数 1.4. 同时传递事件对象和自定义参数 React 组件 2.1. 组件是什么 2.2. 组件基础使用 useState:状态管理 3.1. 基础使用 3.2. 状态的修改规则 3.3. 修改对象状态 基础样式 4.1. 行…...
x264、x265、libaom 编码对比实验
介绍 x264 是一个开源的高性能 H.264/MPEG-4 AVC 编码器,它以其优秀的压缩比和广泛的适用性而闻名。x265 是一种用于将视频流编码成 H.265/MPEG-H HEVC 压缩格式的免费软件库和应用程序,以其下一代压缩能力和卓越的质量而闻名 。作为 x264 的继任者,x265 支持 HEVC 的 Main、…...

c++网络编程实战——开发基于ftp协议的文件传输模块(二) 配置ftp服务与手动执行ftp命令
配置FTP服务 一.前言 博主的环境是阿里云服务器,操作系统版本为 ubuntu20.04,一下所有操作都基于以上环境下进行的操作,同时为了简化操作我将开放同一个云服务器的不同端口,让它同时充当服务端和客户端,大家如果想测试效果更好且…...
Sphinx 安装相关指令解释
安装指令 pip3 install sphinx-autobuildpip3 install sphinx_rtd_themepip3 install sphinx_markdown_tablepip3 install sphinx_markdown_tables pip3 install sphinx-autobuild 功能:安装 sphinx-autobuild 包。作用:sphinx-autobuild 是一个工具&am…...
npm下载包-更改默认缓存目录
npm(Node Package Manager)的缓存目录是npm用于存储已下载包的本地位置,以便在后续安装相同包时能够快速复用,从而节省时间和带宽。npm缓存目录的具体位置会根据操作系统的不同而有所差异。 Windows系统 在Windows系统中&#x…...

PWM再理解(1)
前言 昨天过于劳累,十点睡觉,本来想梳理一下PWM,今天补上。 PWM内涵 PWM全称:Pulse Width Modulation,也就是脉宽调制的意思,字面意思理解就是对脉冲的宽度进行改变。准确就是通过数字输出对模拟电路进行…...

CSPVD 智慧工地安全帽安全背心检测开发包
CSPVD SDK适用于为各种智慧工地应用增加安全防护穿戴合规的检测能力,能够有效检测未戴安全帽和未穿 安全背心的人员,提供Web API和原生API。官方下载:CSPVD工地安全防护检测 1、目录组织 CSPVD开发包的目录组织说明如下: xlpr_…...
给常用Docker命令起别名,提高效率
在日常的开发和运维工作中,Docker是一款非常常用的工具。为了提高工作效率,我们可以为一些常用的Docker命令设置别名,这样可以更快速地执行这些命令。以下是如何给常用Docker命令起别名的详细步骤。 修改/root/.bashrc文件 首先,…...
基于深度学习的草莓成熟度实时检测系统(UI界面+YOLOv8/v7/v6/v5模型+完整代码与数据集)
1. 引言 在农业领域,草莓的成熟度检测是保证果实品质的重要环节。传统的方法依赖于人工经验,不仅耗时费力,还容易出错。本文介绍如何使用YOLO(You Only Look Once)系列模型(YOLOv8/v7/v6/v5)构…...

【devops】ttyd 一个web版本的shell工具 | web版本shell工具 | web shell
一、什么是 TTYD ttyd是在web端一个简单的服务器命令行工具 类似我们在云厂商上直接ssh链接我们的服务器输入指令一样 二、安装ttyd 1、macOS Install with Homebrew: brew install ttydInstall with MacPorts: sudo port install ttyd 2、linux Binary version (recommend…...

超短脉冲激光自聚焦效应
前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应,这是一种非线性光学现象,主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场,对材料产生非线性响应,可能…...
java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别
UnsatisfiedLinkError 在对接硬件设备中,我们会遇到使用 java 调用 dll文件 的情况,此时大概率出现UnsatisfiedLinkError链接错误,原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用,结果 dll 未实现 JNI 协…...

大数据零基础学习day1之环境准备和大数据初步理解
学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 (1)设置网关 打开VMware虚拟机,点击编辑…...

屋顶变身“发电站” ,中天合创屋面分布式光伏发电项目顺利并网!
5月28日,中天合创屋面分布式光伏发电项目顺利并网发电,该项目位于内蒙古自治区鄂尔多斯市乌审旗,项目利用中天合创聚乙烯、聚丙烯仓库屋面作为场地建设光伏电站,总装机容量为9.96MWp。 项目投运后,每年可节约标煤3670…...

深入解析C++中的extern关键字:跨文件共享变量与函数的终极指南
🚀 C extern 关键字深度解析:跨文件编程的终极指南 📅 更新时间:2025年6月5日 🏷️ 标签:C | extern关键字 | 多文件编程 | 链接与声明 | 现代C 文章目录 前言🔥一、extern 是什么?&…...
【Java学习笔记】BigInteger 和 BigDecimal 类
BigInteger 和 BigDecimal 类 二者共有的常见方法 方法功能add加subtract减multiply乘divide除 注意点:传参类型必须是类对象 一、BigInteger 1. 作用:适合保存比较大的整型数 2. 使用说明 创建BigInteger对象 传入字符串 3. 代码示例 import j…...

【MATLAB代码】基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),附源代码|订阅专栏后可直接查看
文章所述的代码实现了基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),针对传感器观测数据中存在的脉冲型异常噪声问题,通过非线性加权机制提升滤波器的抗干扰能力。代码通过对比传统KF与MCC-KF在含异常值场景下的表现,验证了后者在状态估计鲁棒性方面的显著优…...
Git常用命令完全指南:从入门到精通
Git常用命令完全指南:从入门到精通 一、基础配置命令 1. 用户信息配置 # 设置全局用户名 git config --global user.name "你的名字"# 设置全局邮箱 git config --global user.email "你的邮箱example.com"# 查看所有配置 git config --list…...
深入理解Optional:处理空指针异常
1. 使用Optional处理可能为空的集合 在Java开发中,集合判空是一个常见但容易出错的场景。传统方式虽然可行,但存在一些潜在问题: // 传统判空方式 if (!CollectionUtils.isEmpty(userInfoList)) {for (UserInfo userInfo : userInfoList) {…...

关于easyexcel动态下拉选问题处理
前些日子突然碰到一个问题,说是客户的导入文件模版想支持部分导入内容的下拉选,于是我就找了easyexcel官网寻找解决方案,并没有找到合适的方案,没办法只能自己动手并分享出来,针对Java生成Excel下拉菜单时因选项过多导…...