Kafka学习笔记(十)—Kafka文件存储机制

一、日志存储

Kafka的消息以日志文件的形式进行存储。不同主题下不同分区的消息是分开存储的。同一个分区的不同副本也是以日志的形式,分布在不同的broker上存储

查看/tmp/kafka-logs目录,假设有4个partition

在Kafka文件存储中,同一个topic下有多个不同的partition,每个partiton为一个目录, partition的名称规则为:topic名称+有序序号, 第一个序号从0开始计,最大的序号为partition数量减1,partition是实际物理上的概念,而topic是逻辑上的概念

看起来,日志的存储是以副本为单位的。在程序逻辑上,日志确实是以副本为单位的,每个副本对应一个log对象。但实际在物理上,一个log又划分为多个segment进行存储

二、为什么需要segment?

Kafka producer不断发送消息,必然会引起partition文件的无限扩张,这样对于消息文件的维护以及已经被消费的消息的清理带来严重的影响,所以这里以segment为单位又将partition细分

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

segment文件由两部分组成,分别为“.index”文件和“.log”文件,分别表示segment索引文件和数据文件

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

三、日志定位

index文件,里面存储的是n对key-value,其中key是message在log文件中的编号,value值表示该消息的物理偏移地址。

index文件中并没有为数据文件中的每条消息都建立索引,而是采用了稀疏存储的方式,每隔一定字节的数据建立一条索引。这样避免了索引文件占用过多的空间,从而可以将索引文件保留在内存中,但缺点是没有建立索引的message不能一次定位到其在log文件中的位置,这种情况下就需要做一次顺序扫描,不过这次顺序扫描的范围很小

从partition中通过offset查找message流程:
读取offset=170420的消息

  1. 首先查找segment文件,所有文件名称被维护在concurrentSkipListMap中,根据二分查找法从上面三个文件:00000.index,170410.index,239430.index(前面0这里省略) 中定位到第二个文件
  2. 打开这个segment的index文件,继续用二分查找法找到offset小于或者等于指定offset的索引条目中最大的那个offset,这里170410 + 8 = 170418,定位到[8,1325]
  3. 根据[8,1325]定位到00000000000000170410.log文件中的1325的位置进行顺序读取,找到offset = 170420的message

Kafka的Message存储采用了分区(Partition),分段(LogSegment)和稀疏索引来优化性能

参考

https://blog.csdn.net/u013256816/article/details/71091774

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值