!&'&'&()*+,-.*.,/.*010'%
在 Kafka 文件存储中,同一个 topic 下有多个不同的 partition,每个 partiton 为一个目录,
partition 的名称规则为:topic 名称+有序序号,第一个序号从 0 开始计,最大的序号为
partition 数量减 1,partition 是实际物理上的概念,而 topic 是逻辑上的概念。
上面提到 partition 还可以细分为 segment,这个 segment 又是什么?如果就以 partition 为
最小存储单位,我们可以想象当 Kafka producer 不断发送消息,必然会引起 partition 文件
的无限扩张,这样对于消息文件的维护以及已经被消费的消息的清理带来严重的影响,所
以这里以 segment 为单位又将 partition 细分。每个 partition(目录)相当于一个巨型文件被
平均分配到多个大小相等的 segment(段)数据文件中(每个 segment 文件中消息数量不一
定相等)这种特性也方便 old segment 的删除,即方便已被消费的消息的清理,提高磁盘
的利用率。每个 partition 只需要支持顺序读写就行,segment 的文件生命周期由服务端配
置参数(log.segment.bytes,log.roll.{ms,hours}等若干参数)决定。
segment 文件由两部分组成,分别为“.index”文件和“.log”文件,分别表示为 segment 索引
文件和数据文件。这两个文件的命令规则为:partition 全局的第一个 segment 从 0 开始,
后续每个 segment 文件名为上一个 segment 文件最后一条消息的 offset 值,数值大小为
64 位,20 位数字字符长度,没有数字用 0 填充,如下:
********************&
********************
**************.2*).*&
**************.2*).*
**************(%+)%*&
**************(%+)%*
以上面的 segment 文件为例,展示出 segment:00000000000000170410 的“.index”文件
和“.log”文件的对应的关系,如下图:
如上图,“.index”索引文件存储大量的元数据,“.log”数据文件存储大量的消息,索引文件
中的元数据指向对应数据文件中 message 的物理偏移地址。其中以“.index”索引文件中的
元数据[3, 348]为例,在“.log”数据文件表示第 3 个消息,即在全局 partition 中表示
170410+3=170413 个消息,该消息的物理偏移地址为 348。