Kafka消息存储

news/2024/7/24 12:09:27 标签: kafka

一、层次结构

在这里插入图片描述

具体到某个broker上则是, 数据目录/分区名/日志相关文件集合。其中日志文件集合内包括.log文件, index索引文件和.timeindex时间戳索引文件。

二、.log 结构

.log中记录具体的消息。一般消息由header和body组成, 这点儿在Kafka消息中也同样适用。

message

MESSAGE=OVERHEAD+RECORD
OVERHEAD=xxx

v0

RECORD = CRC32+BODY
BODY = magic + attributes + key_len + key + val_len + value
在这里插入图片描述

v1

RECORD = CRC32+BODY
BODY = magic + timestamp + attributes + key_len + key + val_len + value
在这里插入图片描述

v2

在这里插入图片描述

message set

网络传输和存储的基本单位, 也是消息压缩的基本单位。相当于在bit, byte之上page的概念, 只不过叠加更多的约束。
不同颗粒度与存储体系下的能力相对应。

file name

第一条记录的逻辑offset, 这样不需要读取文件内容便知道offset, 充分利用信息位置。

三、.index文件

.index文件是一种稀疏索引。稀疏索引是内存占用, 磁盘占用和查找时间的折中。索引的内容为索引key和对应的物理偏移量。每个索引key的写入受索引项增加速率和索引文件大小限制。索引项增加速率就是数据写入字节数log.index.interval.bytes。另一个是索引文件分割, 如日志文件大小(log.segment.bytes),时间大小(log.roll.ms,hours),索引大小(log.index.size.max.bytes),追加消息的偏移量过大超过了Integer.MAX_VALUE。

文件名称为整个日志段的base offset。其中的索引项记录逻辑offset对应的物理position。每个索引项占8个字节, 前面4个是相对偏移量(absolute offset-base offset, 相对偏移比绝对偏移占用的空间更小), 后者是文件中的物理偏移量(第一个字节在文件中的位置)。
基于索引检索消息时, Kafka基于ConcurrentSkipListMap定位到base offset对应的索引文件, 而后在索引文件内通过二分查找得到对应的物理偏移量。

四、.timeIndex

最大timestamp和逻辑offset的集合, 如果说.index是主键索引, 那么时间戳索引则是二级索引。其查找过程需要先根据.timeIndex查找到不大于目标时间戳的relative offset, 然后通过.index文件定位到对应的物理offset, 然后从.log文件的特定位置开始查找目标位置,最终定位到日志内容。

五、日志删除

作用是删除不再需要消息, 减少磁盘空间占用。

清理触发条件

  1. 按时间清理
  2. 按文件大小清理
  3. 按偏移量清理

日志清理

  1. 清理过程包括2个步骤, 标记和删除;
  2. 标记阶段, 遍历文件夹下的segment, 如果满足触发条件则标记为可删除;
  3. 删除阶段, 删除被标记的segment文件, 更新topic对应的offset;

日志压缩

  1. 针对相同key仅保留最新的消息, 减少磁盘空间占用。整个过程与日志清理类似, 差别在标记后的处理;
  2. 记录最大offset, 扫描整个segment文件, 记录每个key的最大offset到Map中;
  3. 清理消息的value, 扫描整个segment文件, 如果消息offset小于Map中的offset, 则将其value设置为NULL(将消息转变为墓碑消息);
  4. 扫描整个topic下的文件, 创建新的segment文件, 文件名以.swap结尾。一组源日志文件创建一个新的segment文件。

六、高性能IO

IO过程

在这里插入图片描述

常规IO

在这里插入图片描述

性能地下的原因: 1. 太多小的IO; 2. 大量的字节拷贝。

顺序读写

相比于RabbitMQ基于内存堆积消息, Kafka将消息存储在磁盘上。通常我们会觉得磁盘的IO速度非常慢, 但大神们发现IO效率也与IO方式有关。比如对磁盘的顺序读写性能也可以匹配固态盘的随机读写。于是Kafka引入了MessageSet, 对应的是更大的网络包,顺序磁盘IO, 连续的内存块等等, 最终把不稳定的随机stream转换为线性flow。

NIO

在这里插入图片描述

基于NIO可以减少内存拷贝和内核上下文切换, 可参见这篇文件https://developer.ibm.com/articles/j-zerocopy/。

端到端压缩

MessageSet在producer, consumer和broker保持统一的压缩方式, 在数据传输过程中不需要进行解压, 做到尽可能充分利用带宽。

七、小结

本文介绍了Kafka关于日志存储相关的目录结构, 日志内容结构, 日志删除策略以及Kafka使用的高性能IO策略。

八、参考内容

深入Kafka核心设计与与实践原理
https://developer.ibm.com/articles/j-zerocopy/


http://www.niftyadmin.cn/n/5311047.html

相关文章

爬虫实战 - 微博评论数据可视化

简介: 我们都知道在数据比较少的情况下,我们是可以很轻易的获取到数据中的信息。但是当数据比较庞大的时候呢,我们就很难看出来了。尤其是面对现如今数以万计的数据,就更了。 不过好在我们可以通过计算机来帮我们进行分析&#…

wsl(ubuntu)创建用户

我们打卡ubuntu窗口,如果没有创建用户,那么默认是root用户 用户的增删改查 查 查询所有的用户列表 cat /etc/passwd | cut -d: -f1cat /etc/passwd: 这个命令用于显示 /etc/passwd 文件的内容。/etc/passwd 文件包含了系统上所有用户的基本信息。每一…

Java项目部署文档

Linux安装jdk 默认安装到usr/lib/jvm目录下 yum安装 yum -y list java* # 查找全部jdk版本 yum install -y java-1.8.0-openjdk.x86_64 # 安装jdkapt安装 apt-cache search jdk # 查找全部jdk版本 apt-get install openjdk-8-jdk # 安…

9款免费网络钓鱼模拟器详解

根据《2023年网络钓鱼状况报告》显示,自2022年第四季度至2023年第三季度,网络钓鱼电子邮件数量激增了1265%。其中,利用ChatGPT等生成式人工智能工具和聊天机器人的形式尤为突出。 除了数量上的激增外,网络钓鱼攻击模式也在不断进…

【代码片段】【C++】C++11线程安全单例模式

项目中最常用的设计模式还属【单例模式】,C11之后可以实现线程安全的单例模式,不用再通过加锁等操作实现线程安全。并且不用使用指针等容易引起异常的危险操作。 记录下此种线程安全单例模式的写法,以后直接拿来用,只需要修改下类…

Grounding 模型 + SAM 报错

引入 Grounding 目标检测模型串联 SAM 从而实现实例分割任务,目前支持 Grounding DINO 和 GLIP 参考教程 MMDetection-SAM 如果是 Grounding DINO 则安装如下依赖即可 cd playground pip install githttps://github.com/facebookresearch/segment-anything.git pip…

SD-WAN:提升连锁零售企业异地组网稳定性

连锁零售企业往往拥有众多分布在不同地区的分支机构和零售店,为保证企业高效运转,各地区之间的网络连接必须稳定可靠。但基于各地网络基础设施的不同和网络延迟、带宽等限制,异地组网往往并不稳定。在这背景下,SD-WAN成为连锁零售…

静态路由、代理ARP

目录 静态路由静态路由指明下一跳和指明端口的区别代理ARP 我们知道,跨网络通信需要路由 路由有三种类型: 1.直连路由。 自动产生的路由,当网络设备连接到同一网络时,他们可以自动学习到对方的存在。自动学习相邻网络设备的直连信…