文件存储机制

image.png

一个partiton对应一个目录,一个目录一个log, log太大了,查找起来不方便,我们会给log文件切分成多个segment,每个segment对应一个.log文件,一个.index文件.

分片和索引机制

一个Partition有多个segment就是分片,每个segment有多个log文件和index文件,其中index文件就是索引机制.log文件就是存放的消息.

由于生产者生产的消息会不断追加到log文件末尾,为防止log文件过大导致数据定位效率低下,Kafka采取了分片和索引机制,将每个partition分为多个segment。

每个partition(目录)相当于一个巨型文件被平均分配到多个大小相等的segment(段)数据文件中(每个segment 文件中消息数量不一定相等),这种特性也方便old segment的删除,即方便已被消费的消息的清理,提高磁盘的利用率。每个partition只需要支持顺序读写就行,segment的文件生命周期由服务端配置参数(log.segment.bytes,log.roll.{ms,hours}等若干参数)决定。

每个segment对应两个文件——“.index”文件和“.log”文件。

生产者的数据位置存放offset位置存放在index文件里面, log就是数据文件, 一个index文件对应一个log文件.
引入index索引文件的目的就是便于利用二分查找快速定位message位置。

分片的目的是因为Kafka的数据量非常的庞大,如果你不分片的话,数据都在一个文件里面,如果要想在里面查找数据的话,就要翻整个log文件,那样效率太低了,如果分片的话,就可以根据二分查找去文件log文件里面找我需要的数据.

文件命名规则

这两个文件的命令规则为:partition全局的第一个segment从0开始,后续每个segment文件名为上一个segment文件最后一条消息的offset值,数值大小为64位,20位数字字符长度,没有数字用0填充。

这些文件位于一个文件夹下(partition目录),该文件夹的命名规则为:topic名称+分区序号。例如,first这个topic有三个分区,则其对应的文件夹为first-0,first-1,first-2。

00000000000000000000.index # 因为是从头开始消费的,所以偏移量肯定是0 ,这里面的数据就是从0开始到170409的,
00000000000000000000.log
00000000000000170410.index # 这个说明里面的数据偏移量是从170410开始存储的,这里的数据是从170410到239429的
00000000000000170410.log
00000000000000239430.index # 这里说明里面的数据偏移量是从239430开始存储的,这里的数据是从239430往后的
00000000000000239430.log

上面的命名的好处就是查找数据很快,

如何找到offset为3的消息

image.png
“.index”文件存储大量的索引信息,“.log”文件存储大量的数据,索引文件中的元数据指向对应数据文件中message的物理偏移地址。

index和log文件以当前segment的第一条消息的offset命名。下图为index文件和log文件的结构示意图。
找offset为3的message,首先找到索引的文件,发现第二个索引文件是从6开始的,那么3小于6,明显不是这个文件,第一个文件是从0开始的, 说明第一个文件有offset为3的信息,那么就接着往里面找,就能根据index文件记录的log数据文件的消息物理偏移地址找到对应的消息数据了.