kafka在server.properties配置文件中通过log.dir属性指定了Kafka的日志存储路径
实际存储消息的日志文件, 大小固定1G(参数log.segment.bytes可配置), 写满后就会新增一个新的文件, 文件名是第一条消息的偏移量
以偏移量为索引来记录对应的.log日志文件中的消息偏移量
以时间戳为索引, 用来进行一些跟时间相关的消息处理。比如文件清理。
kafka提供了工具查看这些二进制文件
./kafka-dump-log.sh --files /app/kafka/kafka-logs/secondTopic-0/00000000000000000000.log
Kafka都以追加的方式写入新的消息日志。position就是消息记录的起点,size就是消息序列化后的长度。Kafka中的消息日志,只允许追加,不支持删除和修改。所以,当前文件名最大的一个log文件是当前写入消息的日志文件,其他文件都是不可修改的历史日志。
每个Log文件都保持固定的大小。如果当前文件记录不下,会重新创建一个log文件,并以这个log文件写入的第一条消息的偏移量命名。这种设计是为了更方便进行文件映射,加快读消息的效率。
Kafka为了防止日志过多, 给服务器带来压力, 可以设置一些定期删除策略
在检查文件是否过期时,遍历.timeindex文件最大的那一条记录。
log.cleanup.policy: 日志清理策略
有两个选项,delete表示删除日志文件。 compact表示压缩日志文件。
当log.cleanup.policy选择delete时,还有一个参数可以设置,
log.retention.bytes:表示所有日志文件的大小。
当总日志文件大小超过这个阈值后,会删除最早的日志文件。默认是-1,表示不删除。
注意: 压缩文件可能造成文件丢失, 对相同key文件进行压缩, 只会保留最后一条
同一个Topic下的多个Partition单独记录日志文件,并行读取,加快Topic下的数据读取速度。然后index的稀疏索引结构,可以加快log日志检索的速度。
kafka把每个log文件大小固定1g, 在写文件前, 提前占据一块磁盘空间. kafka的log文件只能追加方式结尾写入(顺序写), 就可以直接往提前申请的磁盘空间写入, 不用再去其他磁盘位置找空闲空间
kafka官网测试, 顺序写速度能达到600M/s,基本与内存写速度相当。而随机写的速度就只有100K/s
零拷贝是Linux操作系统提供的一种IO优化机制,而Kafka大量运用零拷贝机制来加速文件读写。
1、mmap文件映射机制
这种方式是在用户态不再缓存整个IO的内容,改为只持有文件的一些映射信息。通过这些映射,"遥控"内核态的文件读写。这样就减少了内核态与用户态之间的拷贝数据大小,提升了IO效率。
2、sendfile文件传输机制
这种机制可以理解为用户态,也就是应用程序不再关注数据的内容,只是向内核态发一个sendfile指令,要他去复制文件就行了。这样数据就完全不用复制到用户态,从而实现了零拷贝。
如果page缓存中的数据没有及时写入到磁盘, 当服务断电, 数据可能丢失. 最安全的方式是写一条数据. 刷一次盘, 也被叫做同步刷盘. 刷盘是linux系统对应了一次fsync的系统调用
刷盘参数配置:
这里可以看出, Kafka并不支持同步刷盘操作。但是在RocketMQ中却支持了这种同步刷盘机制。但是如果真的每来一个消息就调用一次刷盘操作,这是任何服务都无法承受的