Kafka日志索引

偏移量索引

偏移量索引(.index)项的格式如下图所示。每个索引项占用8个字节,分为两个部分。

relativeOffset相对偏移量,表示消息相对于baseOffset 的偏移量,即消息的offset - baseOffset,占用4个字节,当前索引文件的文件名即为 baseOffset 的值。
消息的 offset 占用8个字节,也可以称为绝对偏移量。索引项中没有直接使用绝对偏移量而改为只占用4个字节的相对偏移量(relativeOffset =offset - baseOffset),这样可以减小索引文件占用的空间。

position物理地址,也就是消息在日志分段文件中对应的物理位置(即 .log 文件的 position 字段),占用4个字节。

如下图所示, 如果要查找偏移量为268的消息,过程应该是:首先是定位到 baseOffset 为251的日志分段,然后计算相对偏移量relativeOffset = 268 - 251 = 17 ,之后再在对应的索引文件中找到不大于17的索引项,最后根据索引项中的 position 定位到具体的日志分段文件位置开始查找目标消息。

那么又是如何查找 baseOffset 为 251 的日志分段的呢?这里并不是顺序查找,而是用了跳跃表的结构。Kafka 的每个日志对象中使用了 ConcurrentSkipListMap 来保存各个日志分段,每个日志分段的 baseOffset 作为 key,这样可以根据指定偏移量来快速定位到消息所在的日志分段。

Kafka强制要求索引文件大小必须是索引项大小的整数倍,对偏移量索引文件而言,必须为 8 的整数倍。如果 broker 端参数 log.index.size.max.bytes 配置为 67 ,那么 kafka 在内部会将其转换为 64,即不大于 67,并且满足为 8 的整数倍的条件。

时间戳索引

时间戳索引(.timeindex)项的格式如下图所示,每个索引项占用12 个字节,分为两个部分。

timestamp : 当前日志分段最大的时间戳。

relativeOffset :时间戳所对应的消息的相对偏移量

时间戳索引文件中包含若干时间戳索引项,每个追加的时间戳索引项中的 timestamp 必须大于之前追加的索引项的 timestamp ,否则不予追加。如果 broker 端参数 log.message.timestamp.type 设置为 LogAppendTime,那么消息的时间戳必定能够保持单调递增:相反,如果设置为 CreateTime 类型则无法保证。生产者可以使用类似 ProducerRecord(String topic, Integer partition, Long timestamp, K key, V value) 的方法来指定时间戳的值。即使生产者客户端采用自动插入的时间戳也无法保证时间戳能够单调递增,如果两个不同时间的生产者同时往一个分区中插入消息,那么也会造成当前分区的时间戳乱序。

与偏移量索引文件相似,时间戳索引文件大小必须是索引项大小(12B)的整数倍,如果不满足条件也会进行裁剪。同样假设 broker 端参数 log.index.size.max.bytes 配置为 67 ,那么对应于时间戳索引文件,Kafka 在内部会将其转换为60。

每当写入一定量的消息时,就会在偏移量索引文件和时间戳索引文件中分别增加一个偏移量索引项和时间戳索引项。两个文件增加索引项的操作是同时进行的,但并不意味着偏移量索引中的 relativeOffset 和时间戳索引项中的 relativeOffset 是同一个值。

如果要查找指定时间戳 targetTimeStamp = 1526384718288 开始的消息,首先是找到不小于指定时间戳的日志分段。这里就无法使用跳跃表来快速定位到相应的日志分段了, 需要分以下几个步骤来完成。

步骤1:将 targetTimeStamp 和每个日志分段中的最大时间戳 largestTimeStamp 逐一对比,直到找到不小于 targetTimeStamp 的 largestTimeStamp 所对应的日志分段。日志分段中的 largestTimeStamp 的计算是先查询该日志分段所对应的时间戳索引文件,找到最后一条索引项,若最后一条索引项的时间戳字段值大于0,则取其值,否则取该日志分段的最近修改时间。
步骤2:找到相应的日志分段之后,在时间戳索引文件中使用二分查找算法查找到不大于 targetTimeStamp 的最大索引项,即[1526384718283, 28],如此便找到了一个相对偏移量28。
步骤3:在偏移量索引文件中使用二分算法查找到不大于28的最大索引项,即[26, 838]。
步骤4 :从步骤1中找到日志分段文件中的 838 的物理位置开始查找不小于targetTimeStamp的消息。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值