Kafka消息存储原理

kafka消息存储机制

(一)关键术语java

复习一下几个基本概念,详见上面的基础知识文章。异步

  • Broker:消息中间件处理结点,一个Kafka节点就是一个broker,多个broker可以组成一个Kafka集群。
  • Topic:一类消息,好比page view日志、click日志等都可以以topic的形式存在。Kafka集群可以同一时候负责多个topic的分发。
  • Partition:topic物理上的分组。一个topic可以分为多个partition,每个partition是一个有序的队列。
  • Segment:partition物理上由多个segment组成。如下有具体说明。
  • offset:每个partition都由一系列有序的、不可变的消息组成,这些消息被连续的追加到partition中。partition中的每个消息都有一个连续的序列号叫作offset,用于partition中惟一标识的这条消息。

分析过程分为如下4个步骤:jvm

  • topic中partition存储分布
  • partiton中文件存储方式
  • partiton中segment文件存储结构
  • 在partition中怎样经过offset查找message

经过上述4过程具体分析,咱们就可以清楚认识到kafka文件存储机制的奥秘。socket

二)topic中partition存储分布优化

若是实验环境中Kafka集群仅仅有一个broker。xxx/message-folder为数据文件存储根文件夹。在Kafka broker中server.properties文件配置(參数log.dirs=xxx/message-folder)。好比建立2个topic名称分别为report_push、launch_info, partitions数量都为partitions=4编码

存储路径和文件夹规则为:spa

xxx/message-folder线程

|--report_push-0 设计

|--report_push-1 指针

|--report_push-2

|--report_push-3

|--launch_info-0

|--launch_info-1

|--launch_info-2

|--launch_info-3

在Kafka文件存储中,同一个topic下有多个不一样partition,每个partition为一个文件夹,partiton命名规则为topic名称+有序序号,第一个partiton序号从0開始,序号最大值为partitions数量减1。

 

若是是多broker分布状况,请參考kafka集群partition分布原理分析

(三) partiton中文件存储方式

如下示意图形象说明了partition中文件存储方式:

Alt text

  • 每个partion(文件夹)至关于一个巨型文件被平均分配到多个大小相等segment(段)数据文件里。但每个段segment file消息数量不必定相等,这样的特性方便old segment file高速被删除。(默认状况下每个文件大小为1G)
  • 每个partiton仅仅需要支持顺序读写便可了。segment文件生命周期由服务端配置參数决定。这样作的优势就是能高速删除无用文件。有效提升磁盘利用率。

 

(四) partiton中segment文件存储结构

读者从上节了解到Kafka文件系统partition存储方式。本节深刻分析partion中segment file组成和物理结构。

segment file组成:由2大部分组成。分别为index file和data file,此2个文件一一相应,成对出现,后缀”.index”和“.log”分别表示为segment索引文件、数据文件.

segment文件命名规则:partion全局的第一个segment从0開始,兴许每个segment文件名称为上一个segment文件最后一条消息的offset值。

数值最大为64位long大小。19位数字字符长度,没有数字用0填充。

如下文件列表是笔者在Kafka broker上作的一个实验,建立一个topicXXX包括1 partition,设置每个segment大小为500MB,并启动producer向Kafka broker写入大量数据,例如如下图2所看到的segment文件列表形象说明了上述2个规则:

Alt text

以上述图2中一对segment file文件为例。说明segment中index<—->data file相应关系物理结构例如如下:

Alt text

上述图3中索引文件存储大量元数据,数据文件存储大量消息,索引文件里元数据指向相应数据文件里message的物理偏移地址。

当中以索引文件里元数据3,497为例,依次在数据文件里表示第3个message(在全局partiton表示第368772个message)、以及该消息的物理偏移地址为497。

从上述图3了解到segment data file由不少message组成,如下具体说明message物理结构例如如下:

Alt text

keyword 解释说明 
8 byte offset 在parition(分区)内的每条消息都有一个有序的id号,这个id号被称为偏移(offset),它可以惟一肯定每条消息在parition(分区)内的位置。

即offset表示partiion的第多少message 
4 byte message size message大小 
4 byte CRC32 用crc32校验message 
1 byte “magic” 表示本次公布Kafka服务程序协议版本号号 
1 byte “attributes” 表示为独立版本号、或标识压缩类型、或编码类型。


4 byte key length 表示key的长度,当key为-1时,K byte key字段不填 
K byte key 可选 
value bytes payload 表示实际消息数据。

(五)在partition中怎样经过offset查找message

好比读取offset=368776的message,需要经过如下2个步骤查找。

  • 第一步查找segment file 
  • 上述图2为例。当中00000000000000000000.index表示最開始的文件,起始偏移量(offset)为0.第二个文件00000000000000368769.index的消息量起始偏移量为368770 = 368769 + 1.相同,第三个文件00000000000000737337.index的起始偏移量为737338=737337 + 1。其它兴许文件依次类推。以起始偏移量命名并排序这些文件,仅仅要依据offset 二分查找文件列表,就可以高速定位到具体文件。 当offset=368776时定位到00000000000000368769.index|log
  • 第二步经过segment file查找message 
  • 经过第一步定位到segment file,当offset=368776时。依次定位到00000000000000368769.index的元数据物理位置和00000000000000368769.log的物理偏移地址,而后再经过00000000000000368769.log顺序查找直到offset=368776为止。

从上述图3可知这样作的优势,segment index file採取稀疏索引存储方式,它下降索引文件大小。经过mmap可以直接内存操做,稀疏索引为数据文件的每个相应message设置一个元数据指针,它比稠密索引节省了不少其它的存储空间,但查找起来需要消耗不少其它的时间。

(六)Kafka文件存储机制–实际执行效果

实验环境:

Kafka集群:由2台虚拟机组成

cpu:4核

物理内存:8GB

网卡:千兆网卡

jvm heap: 4GB

具体Kafka服务端配置及其优化请參考:kafka server.properties配置具体解释

Alt text

从上述图5可以看出,Kafka执行时很是少有大量读磁盘的操做。主要是按期批量写磁盘操做。所以操做磁盘很是高效。

这跟Kafka文件存储中读写message的设计是息息相关的。Kafka中读写message有例如如下特色:

写message

  • 消息从java堆转入page cache(即物理内存)。
  • 由异步线程刷盘,消息从page cache刷入磁盘。

读message

  • 消息直接从page cache转入socket发送出去。
  • 当从page cache没有找到相应数据时,此时会产生磁盘IO,从磁 
  • 盘Load消息到page cache,而后直接从socket发出去

(七) 总结

  • Kafka高效文件存储设计特色
  • Kafka把topic中一个parition大文件分红多个小文件段。经过多个小文件段,就easy按期清除或删除已经消费完文件。下降磁盘占用。
  • 经过索引信息可以高速定位message和肯定response的最大大小。
  • 经过index元数据全部映射到memory,可以避免segment file的IO磁盘操做。
  • 经过索引文件稀疏存储,可以大幅下降index文件元数据占用空间大小。
相关文章
相关标签/搜索