Kafka存储内部机制是如何工作的
在这篇文章中,我将帮助你理解kafka是如何存储器数据的。
我发现理解这一点在kafka性能调优时非常有用,同时也对了解每个Borker配置的实际作用有帮助。kafka存储机制的简洁性给了我很大的启发,基于我本人所学知识使用go语言来实现kafka。
那么,kafka的内存存储机制是如何运作的呢?
kafka的数据存储单元是分区 分区是一个有序且不可变的消息队列,新消息会不断追加到分区中,一个分区不能跨越多个Borker,也不能分散在多个硬盘上存储。
Kafka的数据保留策略决定了消息的保留方式
用户可以指定应保留多少数据或数据应保留多长时间,超过这个设定后,Kafka将按照顺序清除消息,无论这些消息是否已被消费。
分区被划分为多个片段(segemnt)
为了避免在单个大文件中查找需要清除的消息时出现速度慢且容易出错的问题,Kafka将分区拆分为多个片段。
当Kafka向分区写入数据时,实际上是向当前活跃片段(segment)写入。一旦该片段的大小达到预设上限,Kafka就会打开一个新的片段,并使其成为新的活跃片段。
片段以其基偏移量命名。一个片段的基偏移量是指大于前序片段中所有偏移量,且小于或等于该片段中所有偏移量的一个偏移量值。
在磁盘上,一个分区是一个目录,每个片段对应一个索引文件和一个日志文件。
$ tree kafka | head -n 6
kafka
├── events-1
│ ├── 00000000003064504069.index
│ ├── 00000000003064504069.log
│ ├── 00000000003065011416.index
│ ├── 00000000003065011416.log
片段日志用于存储消息
每条消息都包含其具体值、偏移量、时间戳、键、消息大小、压缩编解码器、校验和以及消息格式的版本。
磁盘上的数据格式与Broker从生产者通过网络接收的数据以及发送给消费者的完全相同。这种设计使得Kafka能够高效地实现零拷贝的数据传输。
$ bin/kafka-run-class.sh kafka.tools.DumpLogSegments --deep-iteration --print-data-log --files /data/kafka/events-1/00000000003065011416.log | head -n 4
Dumping /data/kafka/appusers-1/00000000003065011416.log
Starting offset: 3065011416
offset: 3065011416 position: 0 isvalid: true payloadsize: 2820 magic: 1 compresscodec: NoCompressionCodec crc: 811055132 payload: {"name": "Travis", msg: "Hey, what's up?"}
offset: 3065011417 position: 1779 isvalid: true payloadsize: 2244 magic: 1 compresscodec: NoCompressionCodec crc: 151590202 payload: {"name": "Wale", msg: "Starving."}
片段索引将消息偏移量映射到日志中的位置
片段索引将消息的偏移量映射到其在日志片段中的位置。
索引文件采用内存映射技术,并且在查找偏移量时使用二分查找方法来找到不大于目标偏移量的最接近偏移量。
索引文件由8字节的条目组成,其中4字节用于存储相对于基偏移量的偏移量差值,另外4字节用于存储位置。偏移量是相对于基偏移量计算的,因此只需要4字节就能存储偏移量。例如:假定基偏移量是10000000000000000000,而不是需要存储随后的偏移量10000000000000000001和10000000000000000002,此时只需存储增量值1和2即可。
Kafka会将压缩的消息一起打包
生产者在发送压缩消息时,会将一批消息一起压缩,然后将其作为包装消息的有效载荷发送出去。同样地,磁盘上的数据格式与之前一样,与Broker从生产者通过网络接收到的数据及发送给消费者的数据完全相同。这意味着,无论是从生产者传送到Broker,还是从Broker分发到消费者,Kafka都能有效地处理和传递已压缩的消息批次。
总结
目前了解的Kafka存储内部机制的运作方式:
- 分区是Kafka的基本存储单元
- 分区被划分为多个片段(segments)
- 每个片段包含两个文件:日志文件和索引文件
- 索引文件将每个偏移量映射到其对应消息在日志中的位置,用于查找消息
- 索引文件存储相对其所属片段基偏移量的偏移量
- 压缩的消息批次会被打包在一个包装消息中作为有效载荷(payload)
- 存储在磁盘上的数据格式与Broker通过网络从生产者接收并发送给消费者的数据完全相同