Kafka-日志索引

news2024/9/22 1:41:38

Kafka的Log日志梳理

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

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

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

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

Kafka提供了工具可以用来查看这些二进制日志文件的内容:

#1、查看timeIndex文件
bin/kafka-dump-log.sh --files /app/kafka/kafka-logs/secondTopic-0/00000000000000000000.timeindex
​
#2、查看index文件
bin/kafka-dump-log.sh --files /app/kafka/kafka-logs/secondTopic-0/00000000000000000000.index
​
#3、查看log文件
bin/kafka-dump-log.sh --files /app/kafka/kafka-logs/secondTopic-0/00000000000000000000.log

log文件追加记录所有消息

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

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

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 index
​
Type:   int
Default:    4096 (4 kibibytes)
Valid Values:   [0,...]
Importance: medium
Update Mode:    cluster-wide

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

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

文件清理机制

Kafka为了防止过多的日志文件给服务器带来过大的压力,会定期删除过期的log文件。

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

  • log.retention.check.interval.ms:定时检测文件是否过期。默认是 300000毫秒,也就是五分钟。

  • log.retention.hours,log.retention.minutes,log.retention.ms。 这组参数表示文件保留多长时间。默认生效的是log.retention.hours,默认值是168小时,也就是7天。如果设置了更高的时间精度,以时间精度最高的配置为准。

  • 在检查文件是否超时时,是以每个.timeindex中最大的那一条记录为准。

过期的日志文件如何处理

  • log.cleanup.policy:日志清理策略。有两个选项,delete表示删除日志文件。compact表示压缩日志文件。

  • 当log.cleanup.policy选择delete时,还有一个参数可以选择。log.retention.bytes:表示所有日志文件的大小。当总的日志文件大小超过这个阈值后,就会删除最早的日志文件。默认是-1,表示无限大。

压缩日志文件虽然不会直接删除日志文件,但是会造成消息丢失。压缩的过程中会将key相同的日志进行压缩,只保留最后一条

Kafka的文件高效读写机制

Kafka的文件结构

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

顺序写磁盘

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

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

零拷贝

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

传统硬件IO的流程:

内核态的内容复制是在内核层面进行的,而零拷贝的技术减少用户态与内核态之间的内容拷贝

具体实现时有两种方式:

  • mmap文件映射机制

    在用户态不再缓存整个IO的内容,改为只持有文件的一些映射信息。通过这些映射,"遥控"内核态的文件读写。这样就减少了内核态与用户态之间的拷贝数据大小,提升了IO效率。

    这种mmap文件映射方式,适合于操作不是很大的文件,通常映射的文件不建议超过2G。所以kafka将.log日志文件设计成1G大小,超过1G就会另外再新写一个日志文件。这就是为了便于对文件进行映射,从而加快对.log文件等本地文件的写入效率。

  • sendfile文件传输机制

    可以理解为用户态,也就是应用程序不再关注数据的内容,只是向内核态发一个sendfile指令,要他去复制文件就行了。这样数据就完全不用复制到用户态,从而实现了零拷贝。

    例如在Kafka中,当Consumer要从Broker上poll消息时,Broker需要读取自己本地的数据文件,然后通过网卡发送给Consumer。这个过程当中,Broker只负责传递消息,而不对消息进行任何的加工。所以Broker只需要将数据从磁盘读取出来,复制到网卡的Socket缓冲区,然后通过网络发送出去。这个过程当中,用户态就只需要往内核态发一个sendfile指令,而不需要有任何的数据拷贝过程。Kafka大量的使用了sendfile机制,用来加速对本地数据文件的读取过程。

合理配置刷盘频率

缓存数据断电就会丢失,这是大家都能理解的,所以缓存中的数据如果没有及时写入到硬盘,也就是常说的刷盘,那么当服务突然崩溃,就会有丢消息的可能。所以,最安全的方式是写一条数据,就刷一次盘,称为同步刷盘。刷盘操作在Linux系统中对应了一个fsync的系统调用。

fsync, fdatasync - synchronize a file's in-core state with storage device

这里提到的in-core state,并不是我们平常开发过程中接触到的缓存,而是操作系统内核态的缓存-pageCache。操作系统为了提升性能,会将磁盘中的文件加载到PageCache缓存中,再向应用程序提供数据。修改文件也是写到PageCache里的。然后操作系统会通过缓存管理机制,在未来的某个时刻将所有的PageCache统一写入磁盘。这个操作就是刷盘。

缓存断掉,造成数据丢失的问题,应用程序其实是没有办法插手的。应用程序不能够决定自己产生的数据在什么时候刷入到硬盘当中,只能尽量频繁的通知操作系统进行刷盘操作。但是,这必然会降低应用的执行性能,而且,也不是能百分之百保证数据安全的。应用程序在这个问题上,只能取舍,不能解决。

Kafka其实在Broker端设计了一系列的参数,来控制刷盘操作的频率。如果对这些频率进行深度定制,是可以实现来一个消息就进行一次刷盘的“同步刷盘”效果的。但是,这样的定制显然会大大降低Kafka的执行效率,这与Kafka的设计初衷是不符合的。所以,在实际应用时,我们通常也只能根据自己的业务场景进行权衡。

  • flush.ms : 多长时间进行一次强制刷盘。

flush.ms
This setting allows specifying a time interval at which we will force an fsync of data written to the log. For example if this was set to 1000 we would fsync after 1000 ms had passed. In general we recommend you not set this and use replication for durability and allow the operating system's background flush capabilities as it is more efficient.
​
Type:   long
Default:    9223372036854775807
Valid Values:   [0,...]
Server Default Property:    log.flush.interval.ms
Importance: medium
  • log.flush.interval.messages:表示当同一个Partiton的消息条数积累到这个数量时,就会申请一次刷盘操作。默认是Long.MAX。

The number of messages accumulated on a log partition before messages are flushed to disk

Type:	long
Default:	9223372036854775807
Valid Values:	[1,...]
Importance:	high
Update Mode:	cluster-wide
  • log.flush.interval.ms:当一个消息在内存中保留的时间,达到这个数量时,就会申请一次刷盘操作。他的默认值是空。如果这个参数配置为空,则生效的是下一个参数。

log.flush.interval.ms
The maximum time in ms that a message in any topic is kept in memory before flushed to disk. If not set, the value in log.flush.scheduler.interval.ms is used
​
Type:   long
Default:    null
Valid Values:   
Importance: high
Update Mode:    cluster-wide
  • log.flush.scheduler.interval.ms:检查是否有日志文件需要进行刷盘的频率。默认也是Long.MAX。

log.flush.scheduler.interval.ms
The frequency in ms that the log flusher checks whether any log needs to be flushed to disk

Type:	long
Default:	9223372036854775807
Valid Values:	
Importance:	high
Update Mode:	read-only

Kafka为了最大化性能,默认是将刷盘操作交由了操作系统进行统一管理

小结:Kafka并没有实现写一个消息就进行一次刷盘的“同步刷盘”操作。但是在RocketMQ中却支持了这种同步刷盘机制。如果真的每来一个消息就调用一次刷盘操作,这是任何服务器都无法承受的。思考RocketMQ是怎么实现同步刷盘的呢?

客户端消费进度管理

kafka为了实现分组消费的消息转发机制,需要在Broker端保持每个消费者组的消费进度。而这些消费进度,就被Kafka管理在自己的一个内置Topic中。这个Topic就是_consumer_offsets。这是Kafka内置的一个系统Topic,在日志文件可以看到这个Topic的相关目录。Kafka默认会将这个Topic划分为50个分区。

同时,Kafka也会将这些消费进度的状态信息记录到Zookeeper中。

小结:在早期版本中,Offset确实是存在Zookeeper中的。但是Kafka在很早就选择了将Offset从Zookeeper中转移到Broker上。这也体现了Kafka其实早就意识到,Zookeeper这样一个外部组件在面对三高问题时,是不太"靠谱"的,所以Kafka逐渐转移了Zookeeper上的数据。而后续的Kraft集群,其实也是这种思想的延伸。

另外,这个系统Topic里面的数据是非常重要的,因此Kafka在消费者端也设计了一个参数来控制这个Topic应该从订阅关系中剔除。

public static final String EXCLUDE_INTERNAL_TOPICS_CONFIG = "exclude.internal.topics";
private static final String EXCLUDE_INTERNAL_TOPICS_DOC = "Whether internal topics matching a subscribed pattern should " +
    "be excluded from the subscription. It is always possible to explicitly subscribe to an internal topic.";
public static final boolean DEFAULT_EXCLUDE_INTERNAL_TOPICS = true;

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

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

相关文章

某60内网渗透之frp实战指南2

内网渗透 文章目录 内网渗透frp实战指南2实验目的实验环境实验工具实验原理实验内容frp实战指南2 实验步骤(1)确定基本信息。(2)查看frp工具的基本用法(3)服务端frp的配置(4)客户端frp的配置(5)使用frp服务 frp实战指南2 实验目的 让学员通过该系统的练习主要掌握&#xff1a…

方差分析实例

目录 方差分析步骤 相关概念 基本思想 随机误差 系统误差 组内方差 组间方差 方差的比较 方差分析的前提 1.每个总体都应服从正态分布 2.各个总体的方差必须相同 3.观察值是独立的 原假设成立 备择假设成立 单因素方差分析 提出假设 检验的统计量 水平的均值…

云原生之深入解析Linkerd Service Mesh的功能和使用

一、简介 Linkerd 是 Kubernetes 的一个完全开源的服务网格实现,它通过为你提供运行时调试、可观测性、可靠性和安全性,使运行服务更轻松、更安全,所有这些都不需要对代码进行任何更改。Linkerd 通过在每个服务实例旁边安装一组超轻、透明的…

【卡塔尔世界杯数据可视化与新闻展示】

卡塔尔世界杯数据可视化与新闻展示 前言数据获取与处理可视化页面搭建功能实现新闻信息显示详情查看登录注册评论信息管理 创新点结语 前言 随着卡塔尔世界杯的临近,对于足球爱好者来说,对比赛的数据分析和新闻报道将成为关注的焦点。本文将介绍如何使用…

Ubuntu安装蓝牙模块pybluez以及问题解决方案【完美解决】

文章目录 简介问题及解决办法总结 简介 近期因工程需要在Ubuntu中使用蓝牙远程一些设备。安装Bluetooth的Python第三方软件包pybluez时遇到很多问题,一番折腾后完美解决。此篇博客进行了梳理和总结,供大家参考。 问题及解决办法 pip install pybluez安…

nodejs微信小程序+python+PHP技术下的音乐推送系统-计算机毕业设计推荐

音乐推送系统采取面对对象的开发模式进行软件的开发和硬体的架设,能很好的满足实际使用的需求,完善了对应的软体架设以及程序编码的工作,采取MySQL作为后台数据的主要存储单元,  本文设计了一款音乐推送系统,系统为人…

解决vue3+ts打包,ts类型检查报错导致打包失败

最近拉的开源大屏项目goview,在打包的过程中一直报Ts类型报错导致打包失败,项目的打包命令为: "build": "vue-tsc --noEmit && vite build" 是因为 vue-tsc --noEmit 是 TypeScript 编译器(tsc&#…

054:vue工具 --- BASE64加密解密互相转换

第054个 查看专栏目录: VUE ------ element UI 专栏目标 在vue和element UI联合技术栈的操控下,本专栏提供行之有效的源代码示例和信息点介绍,做到灵活运用。 (1)提供vue2的一些基本操作:安装、引用,模板使…

正态总体的假设检验

一、三种情况 1.均值μ的假设检验 (1)σ已知 (2)σ未知 2.方差σ的假设检验 二、例题

【MySQL】数据库基础入门 安装MySQL

目录 介绍: 安装MySQL: 设置 root 账号密码 2.配置环境变量 2.找到 Path 系统变量, 点击 "编辑" 介绍: MySQL是一个开源的关系型数据库管理系统(RDBMS),它是一种用于管理和存储数据的软件。 安装MySQL: …

车规MCU应用场景及国产替代进展

目录 1.车规MCU应用场景 1.1 车身域 1.2 动力底盘域 1.3 座舱域和智驾域 1.4 网联域 2.国产替代进展 3.小结 前面一篇文章征途漫漫:汽车MCU的国产替代往事-CSDN博客对车规MCU国产替代的背景与一些往事进行了简单叙述,今天来聊聊车规MCU具体会在汽车哪些地方用…

听GPT 讲Rust源代码--src/tools(14)

File: rust/src/tools/rust-analyzer/crates/cfg/src/lib.rs 在Rust源代码中,rust/src/tools/rust-analyzer/crates/cfg/src/lib.rs这个文件是Rust语言分析器(Rust Analyzer)的一部分,用于处理和管理条件编译指令(Cond…

OceanBase 4.2.1社区版 最小资源需求安装方式

OceanBase 4.2.1社区版 最小资源需求安装方式 资源需求 资源需求分析 observer Memory 控制参数: memory_limit_percentage 默认80% memory_limit 直接设定observer Memory 大小 System memory 可设为1G 租户内存:sys租户内存设为1G,OCP需要的租户oc…

使用netcore编写对比excel差异

一、新建项目Vlook项目 using MiniExcelLibs; using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Data; using System.IO;namespace Vlook {internal class Program{static void Main(string[] args){var dir App…

前端视角看 Docker : 基础命令全面指南

引言 Docker是一种开源的容器化平台,它允许开发者将应用程序和其依赖打包在一个轻量级的、可移植的容器中。这使得应用程序在不同的环境中部署变得简单且高效。本文将介绍Docker的一些基础命令和概念,帮助初学者快速上手。 1. Docker简介 Docker使用…

设计模式——享元模式(结构型)

引言 享元模式是一种结构型设计模式, 它摒弃了在每个对象中保存所有数据的方式, 通过共享多个对象所共有的相同状态, 让你能在有限的内存容量中载入更多对象。 问题 假如你希望在长时间工作后放松一下, 所以开发了一款简单的游戏…

二十七、读写文件

二十七、读写文件 27.1 文件类QFile #include <QCoreApplication>#include<QFile> #include<QDebug>int main(int argc, char *argv[]) {QCoreApplication a(argc, argv);QFile file("D:/main.txt");if(!file.open(QIODevice::WriteOnly | QIODe…

基于 Gin 的 HTTP 代理上网行为记录 demo

前言: 前端时间写了好几篇使用 Gin 框架来做 HTTP 代理 demo 的文章&#xff0c;然后就想着做一个记录上网行为的小工具&#xff0c;就是简单记录看看平时访问了什么网站&#xff08;基于隧道代理的&#xff0c;不是中间人代理&#xff0c;所以只能记录去了哪里&#xff0c;不能…

智能优化算法应用:基于JAYA算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于JAYA算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于JAYA算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.JAYA算法4.实验参数设定5.算法结果6.参考文献7.MA…

算法设计基础——综合

算法设计基础中最基础的几种算法&#xff1a;分治法、减治法、贪心法、动态规划法、回溯法基本都掌握后&#xff0c;我们现在可以对这些算法做整体的比较&#xff0c;本次实验使用蛮力法、动态规划法、回溯法来求解0/1背包问题&#xff0c;来比较各个算法的优劣。 1. 蛮力法 …