Kafka文件存储

参考 : Kafka文件存储机制那些事

1、topic 按照partition存储,每个partition为一个目录,partiton命名规则为topic名称+有序序号

Kafka文件存储

2、partition中的存储–分段(segment)

下面是segment存储方式:
        一个partition被切割成多个相同大小的segment(这个是由log.segment.bytes 决定,控制每个segment的大小)

Kafka文件存储

3、partiton中segment文件存储结构

接下来看看segment的存储结构,本节深入分析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填充。
  • 以及.timeindex文件。(0.8版本之前的kafka没有timeindex文件), 是kafka的具体时间日志

主要分成数据文件xxx.log,和索引文件xxx.index, 两个文件相对应的, 前缀相同。

为了方便观察分段, 我将log.segment.bytes设置成102400,即100KB. 下图为segment的分布情况:

Kafka文件存储

对segment file文件为例,说明segment中index<—->data file对应关系物理结构如下:

Kafka文件存储

从上图可以看到 kafka的优化:其中以索引文件中元数据3,497为例,依次在数据文件中表示第3个message(在全局partiton表示第368772个message)、以及该消息的物理偏移地址为497。

为数据文件建索引

Kafka文件存储

索引优化: 稀疏存储,每隔一定字节的数据建立一条索引。

4、segment data file由许多message组成,下面详细说明message物理结构如下:

Kafka文件存储

注意索引文件中的position 不是消息的offset, 而是message在segment中的物理位置。

5、在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的物理偏移地址(索引文件中的position),然后再通过00000000000000368769.log顺序查找直到offset=368776为止。
从上述图3可知这样做的优点,segment index file采取稀疏索引存储方式,它减少索引文件大小,通过mmap可以直接内存操作,稀疏索引为数据文件的每个对应message设置一个元数据指针,它比稠密索引节省了更多的存储空间,但查找起来需要消耗更多的时间。