Kafka日志文件存储

日志文件

kafka在server.properties配置文件中通过log.dir属性指定了Kafka的日志存储路径

核心文件

1. log文件

实际存储消息的日志文件, 大小固定1G(参数log.segment.bytes可配置), 写满后就会新增一个新的文件, 文件名是第一条消息的偏移量

2. index文件

以偏移量为索引来记录对应的.log日志文件中的消息偏移量

3. timeindex文件

以时间戳为索引, 用来进行一些跟时间相关的消息处理。比如文件清理。

文件查看

kafka提供了工具查看这些二进制文件

cs 复制代码
./kafka-dump-log.sh --files /app/kafka/kafka-logs/secondTopic-0/00000000000000000000.log

log文件追加消息

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

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

index和timeindex索引

  1. index和timeindex存的offset都是相对偏移量, 可以节省空间, 绝对偏移量 = 日志文件名+相对偏移量
  2. 两个索引不会每写入一条消息就建立索引, 而是Broker每写入40KB的数据,就建立一条索引。由参数log.index.interval.bytes配置
  3. index文件类似于数据结构的跳表, 可以加速查询log文件效率, timeindex可以做跟时间相关的处理, 例如文件清理. 这也是kafka消费者能够从某个offset或者某个时间点读消息的原因

文件清理机制

Kafka为了防止日志过多, 给服务器带来压力, 可以设置一些定期删除策略

判断过期

  • 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文件进行压缩, 只会保留最后一条

高效读写机制

1. 文件结构

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

2. 顺序写

kafka把每个log文件大小固定1g, 在写文件前, 提前占据一块磁盘空间. kafka的log文件只能追加方式结尾写入(顺序写), 就可以直接往提前申请的磁盘空间写入, 不用再去其他磁盘位置找空闲空间

kafka官网测试, 顺序写速度能达到600M/s,基本与内存写速度相当。而随机写的速度就只有100K/s

3. 零拷贝

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

1、mmap文件映射机制

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

2、sendfile文件传输机制

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

刷盘机制

如果page缓存中的数据没有及时写入到磁盘, 当服务断电, 数据可能丢失. 最安全的方式是写一条数据. 刷一次盘, 也被叫做同步刷盘. 刷盘是linux系统对应了一次fsync的系统调用

刷盘参数配置:

  • flush.ms : 多少毫秒进行一次强制刷盘
  • log.flush.interval.messages:表示当同一个Partiton的消息条数积累到这个数量时,就会申请一次刷盘操作。默认是Long.MAX。
  • log.flush.interval.ms:当一个消息在内存中保留的时间,达到这个数量时,就会申请一次刷盘操作。他的默认值是空。如果这个参数配置为空,则生效的是下一个参数。
  • log.flush.scheduler.interval.ms:检查是否有日志文件需要进行刷盘的频率。默认也是Long.MAX。

这里可以看出, Kafka并不支持同步刷盘操作。但是在RocketMQ中却支持了这种同步刷盘机制。但是如果真的每来一个消息就调用一次刷盘操作,这是任何服务都无法承受的

相关推荐
qq_5470261797 小时前
Kafka 常见问题
kafka
core5127 小时前
flink sink kafka
flink·kafka·sink
飞来又飞去8 小时前
kafka sasl和acl之间的关系
分布式·kafka
张伯毅14 小时前
Flink SQL 支持 kafka 开启 kerberos 权限控制.
sql·flink·kafka
darkdragonking17 小时前
OpenEuler 22.03 不依赖zookeeper安装 kafka 3.3.2集群
kafka
saynaihe1 天前
安全地使用 Docker 和 Systemctl 部署 Kafka 的综合指南
运维·安全·docker·容器·kafka
隔着天花板看星星1 天前
Spark-Streaming集成Kafka
大数据·分布式·中间件·spark·kafka
太阳伞下的阿呆2 天前
kafka常用命令(持续更新)
分布式·kafka
BUTCHER52 天前
Kafka安装篇
分布式·kafka
若雨叶2 天前
Kafka实现监听多个topic
分布式·kafka