topic中partition存储分布

一个broker

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

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

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名称+partitionNumber,第一个partiton序号从0开始,序号最大值为partitions数量减1。

如果是多broker分布情况,请參考kafka集群partition分布原理分析

kafka集群partition分布原理分析

下面以一个Kafka集群中4个Broker举例,创建1个topic包含4个Partition,2 Replication;数据Producer流动如图所示:

image.png

当集群中新增2节点,Partition增加到6个时分布情况如下:

image.png

副本分配逻辑规则如下:

  • 在Kafka集群中,每个Broker都有均等分配Partition的Leader机会。
  • 上述图Broker Partition中,箭头指向为副本,以Partition-0为例:broker1中parition-0为Leader,Broker2中Partition-0为副本。
  • 上述图种每个Broker(按照BrokerId有序)依次分配主Partition,下一个Broker为副本,如此循环迭代分配,多副本都遵循此规则。

副本分配算法如下:

  • 将所有N Broker和待分配的i个Partition排序.
  • 将第i个Partition分配到第(i mod n)个Broker上.
  • 将第i个Partition的第j个副本分配到第((i + j) mod n)个Broker上.

partiton中文件存储方式

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

image.png

  • 每一个partion(文件夹)相当于一个巨型文件被平均分配到多个大小相等segment(段)数据文件里。
    但每一个段segment file消息数量不一定相等,这样的特性方便old segment file高速被删除。(默认情况下每一个文件大小为1G)
  • 每一个partiton仅仅须要支持顺序读写即可了。segment文件生命周期由服务端配置參数决定。

这样做的优点就是能高速删除无用文件。有效提高磁盘利用率。

partiton中segment文件存储结构

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

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

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

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

image.png

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

image.png

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

.index文件中存储的格式为offset-address,当中以索引文件里元数据3,497为例,依次在数据文件里表示第3个message(在全局partiton表示第368772个message)、以及该消息的物理偏移地址为497。 index文件中只存储相对offset的目的是节省存储空间。

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

image.png

在partition中怎样通过offset查找message

比如读取offset=368776的message,须要通过以下2个步骤查找。

  • 第一步查找segment file 上述图2为例。当中00000000000000000000.index表示最开始的文件,起始偏移量(offset)为0.第二个文件00000000000000368769.index的消息量起始偏移量为368769,第三个文件00000000000000737337.index的起始偏移量为737337。其它文件依次类推。以起始偏移量命名并排序这些文件,仅仅要依据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 这种分片和分段策略,避免了数据量过大时,数据文件文件无限扩张带来的隐患,更有助于消息文件的维护以及被消费的消息的清理。


jacheut
4 声望1 粉丝