Topic在逻辑上可以被认为是一个queue。每条消费都必须指定它的topic,可以简单理解为必须指明把这条消息放进哪个queue里。为了使得Kafka的吞吐率可以水平扩展,物理上把topic分成一个或多个partition,每个partition在物理上对应一个文件夹,该文件夹下存储这个partition的所有消息和索引文件。
每个日志文件都是“log entries”序列,每一个log entry包含一个4字节整型数(值为N),其后跟N个字节的消息体。每条消息都有一个当前partition下唯一的64字节的offset,它指明了这条消息的起始位置。磁盘上存储的消息格式如下:
message length : 4 bytes (value: 1+4+n)
“magic” value : 1 byte
crc : 4 bytes
payload : n bytes
这个“log entries”并非由一个文件构成,而是分成多个segment,每个segment名为该segment第一条消息的offset和“.kafka”组成。另外会有一个索引文件,它标明了每个segment下包含的log entry的offset范围,如下图所示
为数据文件建索引:
稀疏存储,每隔一定字节的数据建立一条索引(这样的目的是为了减少索引文件的大小)。
下图为一个partition的索引示意图:
注:
1.现在对6.和8建立了索引,如果要查找7,则会先查找到8然后,再找到8后的一个索引6,然后两个索引之间做二分法,找到7的位置
通过调用kafka自带的工具,可以看到日志下的数据信息
/bin/bash kafka-run-class.sh kafka.tools.DumpLogSegments --files /tmp/kafka-logs/test_8-0/00000000000000000350.log --print-data-log --verify-index-only
Dumping /tmp/kafka-logs/test_8-0/00000000000000000350.log
Starting offset: 350
offset: 350 position: 0 isvalid: true payloadsize: 1 magic: 0 compresscodec: NoCompressionCodec crc: 3860515739 keysize: 1 key: 0 payload: 0
offset: 351 position: 28 isvalid: true payloadsize: 1 magic: 0 compresscodec: NoCompressionCodec crc: 1172048828 keysize: 1 key