kafka⽂文件系统设计 
李志涛 
lizhitao@meituan.com 
平台业务部移动后台组
Kafka简要说明 
topic中partition存储分布 
partiton⽂文件存储⽅方式 
partiton中segment⽂文件存储结构 
如何在partition中快速定位segment file 
如何在segment file查找msg chunk 
实际效果
Kafka简要说明 
Producer 1 Producer 2 
Broker 1 Broker 2 Broker 3 Broker 4 
push-group 
Consumer 2 
Zookeeper 
关键特⾊色 
• 可伸缩架构 
• ⾼高吞吐量 
• consumer⾃自动负载均衡 
• ⽀支持集群多副本 
Consumer 3 
topic1/part-0 
/part-4 
topic1/part-1 
/part-5 
topic1/part-2 
/part-6 
topic1/part-3 
/part-7
topic中partition存储分布 
topic名称为:report_push 
report_push-0 
report_push 
report_push-1 
report_push-2 
report_push-3 
• 在kafka⽂文件系统中,同⼀一个topic下有多个不同partition,每个partition创建⼀一个⺫⽬目录。
partiton⽂文件存储⽅方式 
上⾯面数字表⽰示记录条数 
下⾯面表⽰示⽂文件⼤大⼩小 
1 501 1001 1501 
• 每个partion(⺫⽬目录)相当于⼀一个巨型⽂文件被平均分配到多个⼤大⼩小相等的多个segment(段)⽂文件 
中。但每个段segment file消息数量不⼀一定相等,这种特性⽅方便old segment file快速被 
删除。 
• 每个partiton只需要⽀支持顺序读写就⾏行了,segment⽂文件⽣生命周期由服务端配置参数决定。 
• ⼩小结: 
主要⺫⽬目的就是提⾼高磁盘利⽤用率和消息处理性能。 
100GB 
500MB 500MB 
……… 
500MB 
segment 
file-0 
segment 
file-1 
segment 
file-2 
分块存储 
或更⼤大 
partition
partiton中segment⽂文件存储结构 
下⾯面介绍⼀一下partion⽂文件存储中segment file组成 
结构。⼀一个商业化消息队列的性能好坏,其⽂文件系 
统存储结构设计是衡量⼀一个消息队列服务程序最关 
键指标之⼀一,他也是消息队列中最核⼼心且最能体现 
消息队列技术⽔水平的部分。在本节中我们将⾛走进 
segment file内部⼀一探究竟。 
segment file组成:由2⼤大部分组成,分别为 
segment data file和segment index file,此2个⽂文 
件⼀一⼀一对应,成对出现.
segment中 index — data file对应关系 
00000000000000000000.log 
消息位置 
00000000000000000000.index message-chunk1 
记录message-chunk1物理位置 
记录message-chunk3物理位置 
记录message-chunk6物理位置 
记录message-chunk8物理位置 
message-chunk2 
message-chunk3 
message-chunk4 
message-chunk5 
message-chunk6 
message-chunk7 
message-chunk8 
消息位置 
消息位置 
消息位置 
⽂文件命名规则:partion全局的第⼀一个segment从0开 
始,后续的segment⽂文件名为上⼀一个全局的partion 
的offset(偏移记录数)加1. 
index为稀疏索引结构,并不存储每条记录的元数据信息,⽽而是与单条或多 
条消息⼤大⼩小⽐比较,如果总消息⼤大⼩小⼤大于该阀值才写⼀一次index,默认阀值 
4096字节
partiton中segment⽂文件存储结构-index 
00000000000000000000.index 
索引⽂文件存储结构: 
每次记录相应log⽂文件记录的相对条数和物理偏移位置位置,共8bytes 
4 byte 当前segment file offset - last seg file offset记录条数 offset 
4 byte 对应segment file物理偏移地址 position 
………
part中segment⽂文件存储结构-data file 
00000000000000000000.log 
数据⽂文件存储msg chunk记录结构: 
4 byte CRC32 
1 byte “magic" 
1 byte “attributes" 
4 byte key length 
K byte key 可选 
4 byte payload length 
val bytes msgs payload 
………. 
chunk data 
message1 
message2 
message3 
message4 
message5 
message6 
8 byte offset 
4 byte chunk size 
每条消息结构 
index 
record size 
data 
msg chunk内 
每条消息索引 
位置从1开始 
⼀一个消息(message chunk)数据块可能包含多条消息,但同⼀一个数据块中的消息只有⼀一 
个offset(partiions第多少msg chunk),所以当⼀一个消息块有多条数据处理完部分数据发 
⽣生异常时,消费者重新去取数据,就会再次取得这个数据块,然后消费过的数据就会被 
重新消费。
数据库稀疏索引例⼦子 
稀疏索引只为数据⽂文件的每个存储块设⼀一个键-指针对,它⽐比稠密索引节省了更多 
的存储空间,但查找给定值的记录需更多的时间。只有当数据⽂文件是按照某个查 
找键排序时,在该查找键上建⽴立的稀疏索引才能被使⽤用,⽽而稠密索引则可以应⽤用 
在任何的查找键。如图2所⽰示,稀疏索引只为每个存储块设⼀一个键-指针对。键值 
是每个数据块中第⼀一个记录的对应值。
如何在partition中快速定位segment file 
同⼀一个topic下有不同分区,每个分区下⾯面会划分为多个(段)⽂文件,只有⼀一个当前⽂文件在 
写,其他⽂文件只读。当写满⼀一个⽂文件(写满的意思是达到设定值)则切换⽂文件,新建 
⼀一个当前⽂文件⽤用来写,⽼老的当前⽂文件切换为只读。⽂文件的命名以起始偏移量来命名。 
看⼀一个例⼦子,假设report_push这个topic下的0-0分区可能有以下这些⽂文件: 
• 00000000000000000000.index 
• 00000000000000000000.log 
• 00000000000000368769.index 
• 00000000000000368769.log 
• 00000000000000737337.index 
• 00000000000000737337.log 
• 00000000000001105814.index 
• 00000000000001105814.log 
……………….. 
其中 00000000000000000000.index表⽰示最开始的⽂文件,起始偏移量为0.第⼆二个⽂文件 
00000000000000368769.index的消息量起始偏移量为368769.同样,第三个⽂文件 
00000000000000737337.index的起始偏移量为737337.以起始偏移量命名并排序这些 
⽂文件,那么当消费者要拉取某个消息起始偏移量位置的数据变的相当简单,只要根据 
传上来的offset**⼆二分查找**⽂文件列表,定位到具体⽂文件,然后将绝对offset减去⽂文件的 
起始节点转化为相对offset,即可开始传输数据。 
例如,同样以上⾯面的例⼦子为例,假设消费者想抓取从第368969消息位置开始的数据, 
则根据368969⼆二分查找,定位到00000000000000368769.log这个⽂文件(368969在 
368769和737337之间),根据索引⽂文件⼆二分搜索可以确定读取数据最⼤大⼤大⼩小
例⼦子
如何在segment file查找msg chunk 
00000000000000000000.index 
1,0 
3,4597 
6,9807 
8,12345 
00000000000000000000.log 
message-chunk1 
message-chunk2 
message-chunk3 
message-chunk4 
message-chunk5 
message-chunk6 
message-chunk7 
message-chunk8 
offset = 1 
offset = 8 
0 
2039 
4597 
6830 
7912 
9807 
1108 
12345 
message-chunkN position
实际效果
kafka的⽂文件系统结构—>总结 
⾼高效⽂文件系统特点 
⼀一个⼤大⽂文件分成多个⼩小⽂文件段。 
多个⼩小⽂文件段,容易定时清除或删除已经消费完⽂文件,减 
少磁盘占⽤用。 
index全部映射到memory直接操作,避免segment file被交 
换到磁盘增加IO操作次数。 
根据索引元数据信息,可以确定consumer每次批量拉取最 
⼤大msg chunk数量。 
索引⽂文件元数据存储⽤用的是相对前⼀一个segment file的 
offset存储,节省空间⼤大⼩小
参考 
kafka-0.8.1-src源码研究 
http://kafka.apache.org/ 
http://blog.csdn.net/lizhitao
Thank you! 
Any Quest?

Kafka文件系统设计

  • 1.
  • 2.
    Kafka简要说明 topic中partition存储分布 partiton⽂文件存储⽅方式 partiton中segment⽂文件存储结构 如何在partition中快速定位segment file 如何在segment file查找msg chunk 实际效果
  • 3.
    Kafka简要说明 Producer 1Producer 2 Broker 1 Broker 2 Broker 3 Broker 4 push-group Consumer 2 Zookeeper 关键特⾊色 • 可伸缩架构 • ⾼高吞吐量 • consumer⾃自动负载均衡 • ⽀支持集群多副本 Consumer 3 topic1/part-0 /part-4 topic1/part-1 /part-5 topic1/part-2 /part-6 topic1/part-3 /part-7
  • 4.
    topic中partition存储分布 topic名称为:report_push report_push-0 report_push report_push-1 report_push-2 report_push-3 • 在kafka⽂文件系统中,同⼀一个topic下有多个不同partition,每个partition创建⼀一个⺫⽬目录。
  • 5.
    partiton⽂文件存储⽅方式 上⾯面数字表⽰示记录条数 下⾯面表⽰示⽂文件⼤大⼩小 1 501 1001 1501 • 每个partion(⺫⽬目录)相当于⼀一个巨型⽂文件被平均分配到多个⼤大⼩小相等的多个segment(段)⽂文件 中。但每个段segment file消息数量不⼀一定相等,这种特性⽅方便old segment file快速被 删除。 • 每个partiton只需要⽀支持顺序读写就⾏行了,segment⽂文件⽣生命周期由服务端配置参数决定。 • ⼩小结: 主要⺫⽬目的就是提⾼高磁盘利⽤用率和消息处理性能。 100GB 500MB 500MB ……… 500MB segment file-0 segment file-1 segment file-2 分块存储 或更⼤大 partition
  • 6.
    partiton中segment⽂文件存储结构 下⾯面介绍⼀一下partion⽂文件存储中segment file组成 结构。⼀一个商业化消息队列的性能好坏,其⽂文件系 统存储结构设计是衡量⼀一个消息队列服务程序最关 键指标之⼀一,他也是消息队列中最核⼼心且最能体现 消息队列技术⽔水平的部分。在本节中我们将⾛走进 segment file内部⼀一探究竟。 segment file组成:由2⼤大部分组成,分别为 segment data file和segment index file,此2个⽂文 件⼀一⼀一对应,成对出现.
  • 7.
    segment中 index —data file对应关系 00000000000000000000.log 消息位置 00000000000000000000.index message-chunk1 记录message-chunk1物理位置 记录message-chunk3物理位置 记录message-chunk6物理位置 记录message-chunk8物理位置 message-chunk2 message-chunk3 message-chunk4 message-chunk5 message-chunk6 message-chunk7 message-chunk8 消息位置 消息位置 消息位置 ⽂文件命名规则:partion全局的第⼀一个segment从0开 始,后续的segment⽂文件名为上⼀一个全局的partion 的offset(偏移记录数)加1. index为稀疏索引结构,并不存储每条记录的元数据信息,⽽而是与单条或多 条消息⼤大⼩小⽐比较,如果总消息⼤大⼩小⼤大于该阀值才写⼀一次index,默认阀值 4096字节
  • 8.
    partiton中segment⽂文件存储结构-index 00000000000000000000.index 索引⽂文件存储结构: 每次记录相应log⽂文件记录的相对条数和物理偏移位置位置,共8bytes 4 byte 当前segment file offset - last seg file offset记录条数 offset 4 byte 对应segment file物理偏移地址 position ………
  • 9.
    part中segment⽂文件存储结构-data file 00000000000000000000.log 数据⽂文件存储msg chunk记录结构: 4 byte CRC32 1 byte “magic" 1 byte “attributes" 4 byte key length K byte key 可选 4 byte payload length val bytes msgs payload ………. chunk data message1 message2 message3 message4 message5 message6 8 byte offset 4 byte chunk size 每条消息结构 index record size data msg chunk内 每条消息索引 位置从1开始 ⼀一个消息(message chunk)数据块可能包含多条消息,但同⼀一个数据块中的消息只有⼀一 个offset(partiions第多少msg chunk),所以当⼀一个消息块有多条数据处理完部分数据发 ⽣生异常时,消费者重新去取数据,就会再次取得这个数据块,然后消费过的数据就会被 重新消费。
  • 10.
    数据库稀疏索引例⼦子 稀疏索引只为数据⽂文件的每个存储块设⼀一个键-指针对,它⽐比稠密索引节省了更多 的存储空间,但查找给定值的记录需更多的时间。只有当数据⽂文件是按照某个查 找键排序时,在该查找键上建⽴立的稀疏索引才能被使⽤用,⽽而稠密索引则可以应⽤用 在任何的查找键。如图2所⽰示,稀疏索引只为每个存储块设⼀一个键-指针对。键值 是每个数据块中第⼀一个记录的对应值。
  • 11.
    如何在partition中快速定位segment file 同⼀一个topic下有不同分区,每个分区下⾯面会划分为多个(段)⽂文件,只有⼀一个当前⽂文件在 写,其他⽂文件只读。当写满⼀一个⽂文件(写满的意思是达到设定值)则切换⽂文件,新建 ⼀一个当前⽂文件⽤用来写,⽼老的当前⽂文件切换为只读。⽂文件的命名以起始偏移量来命名。 看⼀一个例⼦子,假设report_push这个topic下的0-0分区可能有以下这些⽂文件: • 00000000000000000000.index • 00000000000000000000.log • 00000000000000368769.index • 00000000000000368769.log • 00000000000000737337.index • 00000000000000737337.log • 00000000000001105814.index • 00000000000001105814.log ……………….. 其中 00000000000000000000.index表⽰示最开始的⽂文件,起始偏移量为0.第⼆二个⽂文件 00000000000000368769.index的消息量起始偏移量为368769.同样,第三个⽂文件 00000000000000737337.index的起始偏移量为737337.以起始偏移量命名并排序这些 ⽂文件,那么当消费者要拉取某个消息起始偏移量位置的数据变的相当简单,只要根据 传上来的offset**⼆二分查找**⽂文件列表,定位到具体⽂文件,然后将绝对offset减去⽂文件的 起始节点转化为相对offset,即可开始传输数据。 例如,同样以上⾯面的例⼦子为例,假设消费者想抓取从第368969消息位置开始的数据, 则根据368969⼆二分查找,定位到00000000000000368769.log这个⽂文件(368969在 368769和737337之间),根据索引⽂文件⼆二分搜索可以确定读取数据最⼤大⼤大⼩小
  • 12.
  • 13.
    如何在segment file查找msg chunk 00000000000000000000.index 1,0 3,4597 6,9807 8,12345 00000000000000000000.log message-chunk1 message-chunk2 message-chunk3 message-chunk4 message-chunk5 message-chunk6 message-chunk7 message-chunk8 offset = 1 offset = 8 0 2039 4597 6830 7912 9807 1108 12345 message-chunkN position
  • 14.
  • 15.
    kafka的⽂文件系统结构—>总结 ⾼高效⽂文件系统特点 ⼀一个⼤大⽂文件分成多个⼩小⽂文件段。 多个⼩小⽂文件段,容易定时清除或删除已经消费完⽂文件,减 少磁盘占⽤用。 index全部映射到memory直接操作,避免segment file被交 换到磁盘增加IO操作次数。 根据索引元数据信息,可以确定consumer每次批量拉取最 ⼤大msg chunk数量。 索引⽂文件元数据存储⽤用的是相对前⼀一个segment file的 offset存储,节省空间⼤大⼩小
  • 16.
  • 17.