Kafka 日志存储 — 日志索引

server/2025/1/22 19:56:57/

每个日志分段文件对应两个索引文件:偏移量索引文件用来建立消息偏移量到物理地址之间的映射;时间戳索引文件根据指定的时间戳来查找对应的偏移量信息。

1 日志索引

Kafka的索引文件以稀疏索引的方式构造消息的索引。它并不保证每个消息在索引文件中都有对应的索引项。每当写入一定量的消息时,偏移量索引文件和时间戳索引文件分别增加一个索引项。

使用二分查找法来快速定位偏移量的位置。

1.1 日志分段切分的条件

日志分段文件达到一定添加时需要进行切分,其对应的索引文件也需要进行切分。满足以下一项条件即触发切分:

  1. 日志分段文件的大小超过了broker端参数log.segment.bytes配置的值。默认为1GB。
  2. 当前日志分段中消息的最大时间戳与当前系统的时间戳的差值大于log.roll.ms 或log.roll.hourse参数配置的值。log.roll.ms的优先级高,默认值为7天。
  3. 偏移索引文件或时间戳文件的大小达到broker端参数log.index.size.max.bytes配置的值。默认值为10MB。
  4. 追加的消息偏移量与当前日志分段的偏移量之间的差值大于Integer.MAX_VALUE。

1.2 索引文件的创建

对应非活跃的日志分段,其对应的日志及索引文件已经固定,不需要再写入,所以被设定为只读。而当前获取的日志分段,被设定为读写。

索引文件切分时,会关闭当前正在写入的索引文件,并设置为只读模式,同时以可读写模式创建新的索引文件。

在创建索引文件时,会为其预分配log.index.size.max.bytes大小的空间,只有当索引文件进行切分时,才把索引文件裁减到实际的数据大小。

1.3 偏移量索引

每个索引项占用8个字节(8B),分为两部分:

relativeOffset(4B):相对偏移量,消息相对于baseOffset的偏移量。当前索引文件的文件名即为baseOffset的值。

position(4B):消息在日志分段文件中对应的物理地址。

消息偏移量(offset)占用8个字节,而Integer 占用4个字节。上面提到追加的消息偏移量与当前日志分段的偏移量之间的差值大于Integer.MAX_VALUE就触发日志分段切分,因为relativeOffset不能用4个字节表示了。

1.3.1 跳跃表

Skip List,简称跳表。本质是一种可以进行二分查找的有序链表。在原有的有序链表上增加了多级索引。提高了搜索、插入及删除性能。

图 跳跃表结构示意图

采用随机技术决定链表中哪些节点应增加向前指针及在该节点应增加多少个指针。头节点需要足够的指针来满足可能构造最大级数的需要,而尾节点不需要指针域。

查找算法:首先在最高级索引查找最好一个小于目标元素的位置,然后在跳到次高级索引继续查找,直到跳到最底层为止。

1.3.2 查找算法

Kafka的每个日志对象中使用来ConcurrentSkipListMap来保存各个日志分段,每个日志分段的baseOffset作为key。查找算法如下:

  1. 根据跳跃表来确定目标偏移量所在的日志分段及索引文件。
  2. 计算出相对偏移量: 目标偏移量 - 日志分段偏移量。
  3. 在索引文件中找到最大的不大于相对偏移量的索引项。
  4. 根据索引项中的position定位到具体的日志分段文件位置,开始顺序查找目标的最终位置。

Kafka强制要求索引文件的大小必须是索引项大小的整数倍。

1.4 时间戳索引

根据指定的时间戳来查找对应的偏移量信息。

每个索引项占用12个字节,分为两部分:

timestamp(8B):消息对应的时间戳。

relativeOffset(4B):时间戳所对应的消息的相对偏移量。

1.4.1 保证时间戳单调递增

每个追加的时间戳索引项中的timestamp必须大于之前追加的,否则不予追加。如果时间戳类型为LogAppendTime,那么消息的时间戳必定能够保持单调递增。

如果是CreateTime 类型则无法保证。如果两个不同时钟的生产者同时往一个分区中插入消息,则可能会造成当前分区的时间戳乱序。

1.4.2 查找算法

每当写入一定量的消息时,就会在偏移索引文件和时间戳索引文件中分别增加一个索引项。两个文件增加索引操作是同时进行的,但并不意味着两者指向同一个值。

时间戳索引不是通过跳跃表来定位相应的日志片段。步骤如下:

  1. 查找日志分段,将目标时间戳和每个日志分段中的最大时间戳逐一对比,直到找到不小于目标时间戳的对应日志分段。(日志分段的最大时间戳是先查询该日志所对应的时间戳索引文件,找到最好一条索引项,若时间戳字段大于0,则取其值,否则取该日志分段的最近修改时间)
  2. 查找相对偏移量。在时间戳索引中使用二分查找找到不大于目标时间戳的最大索引项,来找到一个相对偏移量。
  3. 在偏移量索引文件中根据这个相对偏移量来查找到其物理位置。
  4. 从物理位置开始顺序查找最大的不小于目标时间戳的消息。

http://www.ppmy.cn/server/160553.html

相关文章

【Vim Masterclass 笔记18】第八章 + S08L35:Vim 的可视化模式(二)

文章目录 S08L35 Visual Mode - Part 21 利用可视化模式控制代码块的缩进2 缩进宽度的设置3 仅对选中区域执行替换操作4 利用可视化模式实现文本对齐 写在前面 本篇为 Vim 可视化模式的第二部分,主要介绍了可视化模式在代码缩进方面的应用。该视频应该录制于 2018 年…

高效实现 Markdown 转 PDF 的跨平台指南20250117

高效实现 Markdown 转 PDF 的跨平台指南 引言 Markdown 文件以其轻量化和灵活性受到开发者和技术写作者的青睐,但如何将其转换为易于分享和打印的 PDF 格式,是一个常见需求。本文整合了 macOS、Windows 和 Linux 三大平台的转换方法,并探讨…

蓝桥杯算法|基础笔记(1)

**时间复杂度** 一、概念理解 时间复杂度是用来衡量算法运行时间随输入规模增长而增长的量级。它主要关注的是当输入规模趋向于无穷大时,算法执行基本操作的次数的增长趋势,而不是精确的运行时间。 二、分析代码中的基本操作 确定关键操作 在一段代码…

opencv笔记2

图像灰度 彩色图像转化为灰度图像的过程是图像的灰度化处理。彩色图像中的每个像素的颜色由R,G,B三个分量决定,而每个分量中可取值0-255,这样一个像素点可以有256*256*256变化。而灰度图像是R,G,B三个分量…

机器学习10-解读CNN代码Pytorch版

机器学习10-解读CNN代码Pytorch版 我个人是Java程序员,关于Python代码的使用过程中的相关代码事项,在此进行记录 文章目录 机器学习10-解读CNN代码Pytorch版1-核心逻辑脉络2-参考网址3-解读CNN代码Pytorch版本1-MNIST数据集读取2-CNN网络的定义1-无注释版…

软考信安24~工控安全需求分析与安全保护工程

1、工控系统安全威胁与需求分析 1.1、工业控制系统概念及组成 工业控制系统是由各种控制组件、监测组件、数据处理与展示组件共同构成的对工业生产过程进行控制和监控的业务流程管控系统。工业控制系统通常简称工控系统(ICS) 。 工控系统通常分为离散制造类和过程控制类两大…

通过idea创建的springmvc工程需要的配置

在创建的spring mvc工程中&#xff0c;使用idea开发之前需要配置文件包括porm.xml、web.xml、springmvc.xml 1、porm.xml 工程以来的spring库&#xff0c;主要包括spring-aop、spring-web、spring-webmvc&#xff0c;示例配置如下&#xff1a; <project xmlns"http:/…

centos设置开机自启的几种方案(frp为例)

下面几种方式任选其一即可 创建自定义systemd服务实现 以frps为例 创建服务文件 vim /etc/systemd/system/frps.service 如果没有vim命令可以使用vi 也可以执行yum install vim 安装一下将该配置粘贴到frps.service中并根据实际情况修改保存 [Unit] DescriptionFRP Server …