目录
1. 概述
Kafka选择把消息直接写入硬盘,而不是写到内存,所以尝试探究这个选择的原因。
2. 写入硬盘的位置
查看配置文件config/server.properties
的log.dirs
属性,默认是/tmp/kafka-logs
,目录下存放的是所有Topic的文件夹,以${topic_name}-${partition_id}
命名。例如topic=test,partition=0
,则对应的文件夹为test-0
。
3. Topic组成
Kafka启动后
Kafka关闭后
00000000000000000000.index
保存消息的位置索引:offset
和position
。
position
保存某条消息在此文件的开始(字节)位置。
假设Topic
test
只有一个分区
现在进来第一条70 bytes的消息,这条消息的位置索引为:offset: 0 position: 0
现在进来第二条80 bytes的消息,这条消息的位置索引为:offset: 1 position: 70
现在进来第三条90 bytes的消息,这条消息的位置索引为:offset: 2 position: 150
…
通过命令fuser -v 00000000000000000000.index
可以查看到
+------+------+--------+---------+
| USER | PID | ACCESS | COMMAND |
+------+------+--------+---------+
| root | 6114 | ....m | java |
+------+------+--------+---------+
....m
表示这个文件通过MMAP(Memory Mapped Files)
方式加载(注:类似内存的“硬盘镜像”)
Kafka启动时就会去加载这个文件,从而能快速给Topic做索引。(Kafka关闭后,这个文件就变成空文件)
00000000000000000000.log
消息的数据文件,所有这个Topic的消息都保存在这个文件中
通过命令fuser -v 00000000000000000000.log
可以查看到
+------+------+--------+---------+
| USER | PID | ACCESS | COMMAND |
+------+------+--------+---------+
| root | 6114 | F.... | java |
+------+------+--------+---------+
F....
表示文件被程序打开写入,因为该Topic有新消息,Kafka能随时(ack后)写入。
open file for writing, F is omitted in default display mode
通过命令解析消息
kafka-run-class kafka.tools.DumpLogSegments --print-data-log --files 00000000000000000000.log
解析结果
offset: 0 position: 0 CreateTime: 1538019310492 isvalid: true keysize: 4 valuesize: 7 magic: 2 compresscodec: NONE producerId: -1 producerEpoch: -1 sequence: -1 isTransactional: false headerKeys: [] key: key1 payload: values1
00000000000000000000.timeindex
保存消息的时间索引:timestamp
和offset
。
这个文件的作用与00000000000000000000.index
的作用类似,不同作用的索引而已。
通过命令fuser -v 00000000000000000000.timeindex
得到的结果与00000000000000000000.index
的一致。
Kafka启动时就会去加载这个文件,从而能快速给Topic做索引。(Kafka关闭后,这个文件剩下最近一条消息的索引)
00000000000000000006.snapshot
Kafka关闭时,记录下一个offset
的位置。
例如,我关闭Kafka前的最后一条消息的offset=5
,则当我关闭Kafka后,会新建一个00000000000000000006.snapshot
文件。当再次启动并关闭Kafka,会新建另一个新的文件,之前的文件不覆盖。
这个文件里面保存的内容没有深究,通过cat
得到的内容:HgK
leader-epoch-checkpoint
没深究,简单运行cat
,内容
0
1
0 0
参考文章
Kafka存储的内部原理(知识点:segment)
fuser
4. 为什么Kafka那么快
Kafka把所有数据写入硬盘,而非内存
利用硬盘的顺序读写,因为并不比内存的随机读取慢。
使用内存的弊端
- Kafka运行在JVM上,消息可以成倍增长
- JVM的GC消耗系统资源
Memory Mapped Files(MMAP)
上面的Topic索引有用到,可自行百度Google。
Zero Copy
没有使用Zero Copy
使用Zero Copy
自行百度Google。简单来说,就是
跳过APP端,底层直接做数据交换
Batch Data
分批提交,而非一条条提交。例如1000条消息或10M消息提交一次。、