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流动如图所示:
当集群中新增2节点,Partition增加到6个时分布情况如下:
副本分配逻辑规则如下:
- 在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中文件存储方式:
- 每一个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个规则:
以上述图2中一对segment file文件为例。说明segment中index<—->data file相应关系物理结构例如以下:
上述图3中索引文件存储大量元数据,数据文件存储大量消息,索引文件里元数据指向相应数据文件里message的物理偏移地址。
.index文件中存储的格式为offset-address,当中以索引文件里元数据3,497为例,依次在数据文件里表示第3个message(在全局partiton表示第368772个message)、以及该消息的物理偏移地址为497。 index文件中只存储相对offset的目的是节省存储空间。
从上述图3了解到segment data file由很多message组成,以下具体说明message物理结构例如以下:
在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 这种分片和分段策略,避免了数据量过大时,数据文件文件无限扩张带来的隐患,更有助于消息文件的维护以及被消费的消息的清理。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。