Kafka日志索引详解以及生产常见问题分析与总结

文章目录

  • 1、Kafka的Log日志梳理
    • 1.1、Topic下的消息是如何存储的?
      • 1.1.1、 log文件追加记录所有消息
      • 1.1.2、 index和timeindex加速读取log消息日志。
    • 1.2、文件清理机制
      • 1.2.1、如何判断哪些日志文件过期了
      • 1.2.2、过期的日志文件如何处理
    • 1.3、Kafka的文件高效读写机制
      • 1.3.1、Kafka的文件结构
      • 1.3.2、顺序写磁盘
      • 1.3.3、零拷贝

1、Kafka的Log日志梳理

这一部分数据主要包含当前Broker节点的消息数据(在Kafka中称为Log日志)。这是一部分无状态的数据,也就是说每个Kafka的Broker节点都是以相同的逻辑运行。这种无状态的服务设计让Kafka集群能够比较容易的进行水平扩展。比如你需要用一个新的Broker服务来替换集群中一个旧的Broker服务,那么只需要将这部分无状态的数据从旧的Broker上转移到新的Broker上就可以了。

1.1、Topic下的消息是如何存储的?

​ 在搭建Kafka服务时,我们在server.properties配置文件中通过log.dir属性指定了Kafka的日志存储目录。实际上,Kafka的所有消息就全都存储在这个目录下。

在这里插入图片描述
这些核心数据文件中,.log结尾的就是实际存储消息的日志文件。他的大小固定为1G(由参数log.segment.bytes参数指定),写满后就会新增一个新的文件。一个文件也成为一个segment文件名表示当前日志文件记录的第一条消息的偏移量。

​ .index和.timeindex是日志文件对应的索引文件。不过.index是以偏移量为索引来记录对应的.log日志文件中的消息偏移量。而.timeindex则是以时间戳为索引。

另外的两个文件,partition.metadata简单记录当前Partition所属的cluster和Topic。leader-epoch-checkpoint文件参见上面的epoch机制。

​ 这些文件都是二进制的文件,无法使用文本工具直接查看。但是,Kafka提供了工具可以用来查看这些日志文件的内容。

#1、查看timeIndex文件
[oper@worker1 bin]$ ./kafka-dump-log.sh --files /app/kafka/kafka-logs/secondTopic-0/00000000000000000000.timeindex 
Dumping /app/kafka/kafka-logs/secondTopic-0/00000000000000000000.timeindex
timestamp: 1661753911323 offset: 61
timestamp: 1661753976084 offset: 119
timestamp: 1661753977822 offset: 175
#2、查看index文件
[oper@worker1 bin]$ ./kafka-dump-log.sh --files /app/kafka/kafka-logs/secondTopic-0/00000000000000000000.index      
Dumping /app/kafka/kafka-logs/secondTopic-0/00000000000000000000.index
offset: 61 position: 4216
offset: 119 position: 8331
offset: 175 position: 12496
#3、查看log文件
[oper@worker1 bin]$ ./kafka-dump-log.sh --files /app/kafka/kafka-logs/secondTopic-0/00000000000000000000.log
Dumping /app/kafka/kafka-logs/secondTopic-0/00000000000000000000.log
Starting offset: 0
baseOffset: 0 lastOffset: 1 count: 2 baseSequence: 0 lastSequence: 1 producerId: 7000 producerEpoch: 0 partitionLeaderEpoch: 11 isTransactional: false isControl: false deleteHorizonMs: OptionalLong.empty position: 0 CreateTime: 1661753909195 size: 99 magic: 2 compresscodec: none crc: 342616415 isvalid: true
baseOffset: 2 lastOffset: 2 count: 1 baseSequence: 2 lastSequence: 2 producerId: 7000 producerEpoch: 0 partitionLeaderEpoch: 11 isTransactional: false isControl: false deleteHorizonMs: OptionalLong.empty position: 99 CreateTime: 1661753909429 size: 80 magic: 2 compresscodec: none crc: 3141223692 isvalid: true
baseOffset: 3 lastOffset: 3 count: 1 baseSequence: 3 lastSequence: 3 producerId: 7000 producerEpoch: 0 partitionLeaderEpoch: 11 isTransactional: false isControl: false deleteHorizonMs: OptionalLong.empty position: 179 CreateTime: 1661753909524 size: 80 magic: 2 compresscodec: none crc: 1537372733 isvalid: true
.......

​ 这些数据文件的记录方式,就是我们去理解Kafka本地存储的主线。对这里面的各个属性理解得越详细,也就表示对Kafka的消息日志处理机制理解得越详细。

1.1.1、 log文件追加记录所有消息

​ 首先:在每个文件内部,Kafka都会以追加的方式写入新的消息日志。position就是消息记录的起点,size就是消息序列化后的长度。Kafka中的消息日志,只允许追加,不支持删除和修改。所以,只有文件名最大的一个log文件是当前写入消息的日志文件,其他文件都是不可修改的历史日志。

​ 然后:每个Log文件都保持固定的大小。如果当前文件记录不下了,就会重新创建一个log文件,并以这个log文件写入的第一条消息的偏移量命名。这种设计其实是为了更方便进行文件映射,加快读消息的效率。

1.1.2、 index和timeindex加速读取log消息日志。

​ 详细看下这几个文件的内容,就可以总结出Kafka记录消息日志的整体方式:

在这里插入图片描述
首先:index和timeindex都是以相对偏移量的方式建立log消息日志的数据索引。比如说 0000.index和0550.index中记录的索引数字,都是从0开始的。表示相对日志文件起点的消息偏移量。而绝对的消息偏移量可以通过日志文件名 + 相对偏移量得到。

​ 然后:这两个索引并不是对每一条消息都建立索引。而是Broker每写入40KB的数据,就建立一条index索引。由参数log.index.interval.bytes定制。

log.index.interval.bytes
The interval with which we add an entry to the offset indexType:	int
Default:	4096 (4 kibibytes)
Valid Values:	[0,...]
Importance:	medium
Update Mode:	cluster-wide

​ index文件的作用类似于数据结构中的跳表,他的作用是用来加速查询log文件的效率。而timeindex文件的作用则是用来进行一些跟时间相关的消息处理。比如文件清理。

​ 这两个索引文件也是Kafka的消费者能够指定从某一个offset或者某一个时间点读取消息的原因。

1.2、文件清理机制

​ Kafka为了防止过多的日志文件给服务器带来过大的压力,他会定期删除过期的log文件。Kafka的删除机制涉及到几组配置属性:

1.2.1、如何判断哪些日志文件过期了

log.retention.check.interval.ms:定时检测文件是否过期。默认是 300000毫秒,也就是五分钟。
log.retention.hours , log.retention.minutes, log.retention.ms 。 这一组参数表示文件保留多长时间。默认生效的是log.retention.hours,默认值是168小时,也就是7天。如果设置了更高的时间精度,以时间精度最高的配置为准。
在检查文件是否超时时,是以每个.timeindex中最大的那一条记录为准。

1.2.2、过期的日志文件如何处理

log.cleanup.policy:日志清理策略。有两个选项,delete表示删除日志文件。 compact表示压缩日志文件。
当log.cleanup.policy选择delete时,还有一个参数可以选择。log.retention.bytes:表示所有日志文件的大小。当总的日志文件大小超过这个阈值后,就会删除最早的日志文件。默认是-1,表示无限大。
​ 压缩日志文件虽然不会直接删除日志文件,但是会造成消息丢失。压缩的过程中会将key相同的日志进行压缩,只保留最后一条。

1.3、Kafka的文件高效读写机制

​ 这是Kafka非常重要的一个设计,同时也是面试频率超高的问题。可以分几个方向来理解。

1.3.1、Kafka的文件结构

​ Kafka的数据文件结构设计可以加速日志文件的读取。比如同一个Topic下的多个Partition单独记录日志文件,并行进行读取,这样可以加快Topic下的数据读取速度。然后index的稀疏索引结构,可以加快log日志检索的速度。

1.3.2、顺序写磁盘

​ 这个跟操作系统有关,主要是硬盘结构。

​ 对每个Log文件,Kafka会提前规划固定的大小,这样在申请文件时,可以提前占据一块连续的磁盘空间。然后,Kafka的log文件只能以追加的方式往文件的末端添加(这种写入方式称为顺序写),这样,新的数据写入时,就可以直接往直前申请的磁盘空间中写入,而不用再去磁盘其他地方寻找空闲的空间(普通的读写文件需要先寻找空闲的磁盘空间,再写入。这种写入方式称为随机写)。由于磁盘的空闲空间有可能并不是连续的,也就是说有很多文件碎片,所以磁盘写的效率会很低。

​ kafka的官网有测试数据,表明了同样的磁盘,顺序写速度能达到600M/s,基本与写内存的速度相当。而随机写的速度就只有100K/s,差距比加大。

1.3.3、零拷贝

​ 零拷贝是Linux操作系统提供的一种IO优化机制,而Kafka大量的运用了零拷贝机制来加速文件读写。

​ 传统的一次硬件IO是这样工作的。如下图所示:

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

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

相关文章

MySQL-MVCC(Multi-Version Concurrency Control)

MySQL-MVCC(Multi-Version Concurrency Control) MVCC(多版本并发控制):为了解决数据库并发读写和数据一致性的问题,是一种思想,可以有多种实现方式。 核心思想:写入时创建行的新版…

【多任务案例:猫狗脸部定位与分类】

【猫狗脸部定位与识别】 1 引言2 损失函数3 The Oxford-IIIT Pet Dataset数据集4 数据预处理4 创建模型输入5 自定义数据集加载方式6 显示一批次数据7 创建定位模型8 模型训练9 绘制损失曲线10 模型保存与预测 1 引言 猫狗脸部定位与识别分为定位和识别,即定位猫狗…

MacOS怎么安装Nacos(附带:Windows系统)

MacOS安装Nacos(一定要配置JDK的环境变量,后面告诉你为什么?) (1)进入Nacos官网,前往githubhomehomehttp://nacos.io/zh-cn/ (2)点击右下角的releases 然后点击Tags 选择…

代码随想录算法训练营第五十七天 | 392.判断子序列 115.不同的子序列

1. 判断子序列 392. 判断子序列 - 力扣(LeetCode) dp[i][j] 表示以下标i-1为结尾的字符串s,和以下标j-1为结尾的字符串t,相同子序列的长度。 class Solution {public boolean isSubsequence(String s, String t) {//dp[i][j] 表示…

Redis7的数据结构

Redis以键-值对的形式存储数据 一、键 1、键的特点 键是一个字符串,这个字符串的内容可以是数字、字符序列,也可以是一个文件的字节序列,甚至空字符串也可以做为key。 在一个数据库中键必须是唯一的。 键最大可以达到512M,但太…

通用收藏管理器Koillection

什么是 Koillection ? Koillection 是一个自托管的收藏管理器,旨在跟踪任何类型的物理(主要)收藏,如书籍、DVD、邮票、游戏……,由于 Koillection 旨在用于任何类型的收藏,它不支持自动下载元数…

STM32 DMA从存储器发送数据到串口

1.任务描述 (1)ds18b20测量环境温度存储到存储器(数组)中。 (2)开启DMA将数组中的内容,通过DMA发送到串口 存在问题,ds18b20读到的数据是正常的,但是串口只是发送其低…

Redis最常见的5种应用场景

Redis作为当今最流行的内存数据库,已经成为服务端加速的必备工具之一。对于Redis为什么那么快?以及Redis采用单线程,但为什么反而获得更高的性能的疑问,在之前的Redis为什么那么快?一文中,已经有所介绍。 …

全新UI彩虹外链网盘系统源码(前后端美化模板)

全新UI彩虹外链网盘系统源码前后端美化模板,支持所有格式文件的上传、生成文件外链、图片外链、音乐视频外链等功能,同时还可以自动生成相应的 UBB 代码和 HTML 代码,支持文本、图片、音乐、视频在线预览。这不仅仅是一个网盘,更是…

证书显示未受信任,生成的证书过期

此时若是导入证书后,证书显示未受信任,则说明我们缺失最新的AppleWWDRCA证书 解决方案: 重新下载AppleWWDRCA并安装。即下载最新的AppleWWDRCA证书,双击安装到“登录”项的钥匙串下;然后再安装你的开发证书或者发布证书…

WebSocket实战之六心跳重连机制

一、前言 WebSocket应用部署到生产环境,我们除了会碰到因为经过代理服务器无法连接的问题(注:该问题可以通过搭建WSS来解决,具体配置请看 WebSocket实战之四WSS配置 ),另外一个问题就是外网环境不稳定经常…

Appium开发

特点 开源免费支持多个平台 IOS(苹果)、安卓App的自动化都支持 支持多种类型的自动化 支持苹果、安卓应用原生界面的自动化支持应用内嵌网络视图的自动化支持手机浏览器(Chrome)中的web网站自动化支持flutter应用的自动化 支持多种编程语言 像selenium一样,可以用多…

react.js在visual code 下的hello World

想学习reacr.js ,就开始做一个hello world。 我的环境是visual code ,所以我找这个环境下的例子。参照: https://code.visualstudio.com/docs/nodejs/reactjs-tutorial 要学习react.js ,还得先安装node.js,我在visual …

面试打底稿④ 专业技能的第四部分

简历原文 抽查部分 了解Python的使用(第一篇关于Python升级版本bug解决的文章斩获6W阅读),用python实现了几篇图像信息隐藏领 域论文的复现(博客中有提及); 了解Django基本框架,写过Django框架的…

【软考】4.2 关系代数

《 关系代数 》 表和表之间的逻辑运算 笛卡尔积:S1 x S2 投影:π;选择某一列(属性);一个关系R的投影操作结果也是一个关系,记作Πa,它由从关系R中选出的A列元素构成;选择…

测开 | Vue速查知识点

文章目录 Vue知识1. Vue 概述2. Vue 代码格式3. Vue 指令3.1 v-bind & v-model3.2 v-on3.3 v-if和v-show3.4 v-for 4. 生命周期 Vue知识 1. Vue 概述 简介: Vue.js(读音 /vjuː/, 类似于 view) 是一套构建用户界面的 渐进式框架。与其他…

CodeCraft-21 and Codeforces Round 711 (Div. 2)A-F

1.Problem - A - Codeforces (1)题意 求一个大于等于n的整数x,满足gcd(x,sum(dig(x)) > 1,dig表示x的各个数位。 (2)思路 考虑最差是满足gcd(x,sum(dig(x)) 2,因此不会枚举很多,直接暴力枚…

Webpack 基础入门以及接入 CSS、Typescript、Babel

一、什么是 Webpack Webpack 是一款 JS 模块化开发的技术框架,其运作原理是将多个 JS 文件关联起来构成可运行的应用程序。 Webpack 拥有丰富的 plugins / loaders 插件生态圈,可以让 js 识别不同的语言如 .css, .scss, .sass, .json, .xml, .ts, .vue…

数据结构:复杂度分析

目录 1 算法效率评估 1.1 实际测试 1.2 理论估算 2 迭代与递归 2.1 迭代 1. for 循环 2. while 循环 3. 嵌套循环 2.2 递归 1. 调用栈 2. 尾递归 3. 递归树 2.3 两者对比 3 时间复杂度 3.1 统计时间增长趋势 3.2 函数渐近上界…

c++的io流

文章目录 1.C语言的输入和输出2.流失是什么3.cIO流3.1c标准io流3.2c文件io流 4.stringstream的简单介绍 1.C语言的输入和输出 C语言中我们用到的最频繁的输入输出方式就是scanf ()与printf(),scanf(): 从标准输入设备(键盘)读取数据,并将值存放在变量中…