首页 > 解决方案 > Kafka分区索引文件

问题描述

所以我在读这个: https ://thehoard.blog/how-kafkas-storage-internals-work-3a29b02e026

关于 kafka 存储内部结构,提出了 2 个问题:

  1. 索引文件中的偏移量似乎是单调增加的,那为什么还要保存呢?为什么不使用文件中行的索引作为偏移量(基于0)并将文件大小减少一半?

  2. 如果我理解正确,日志文件中保存的位置是该消息在分区内的位置(基本上是它的索引)。保存在索引文件中的位置是同一个位置吧?为了快速访问,例如,如果我想要分区的消息 6,我在索引文件中使用二进制搜索查找 6,并使用同一条目中的偏移量,我转到日志文件中的那一行?(例如,如果位置 6 的索引为 7,那么我转到日志文件中的第 7 行)

标签: apache-kafka

解决方案


这是一个有趣的!

诚然,我对 Kafka 内部结构的理解有限,但无论如何我都会尝试破解它。

对于第一个问题

我查看了OffsetIndex.scala的源代码- 似乎relativeOffset()每次创建新条目时都会在方法中计算索引文件中的偏移量部分。除此之外,源代码中的描述说

将偏移量映射到特定日志段的物理文件位置的索引。这个索引可能是稀疏的:也就是说,它可能不会为 log 中的所有消息保存一个条目

因此,根据您分享的参考文章 - 这可能是由于该索引的这种稀疏性质,

偏移量查找使用二分法查找小于或等于目标偏移量的最近偏移量

从解释看来,偏移量只是在增加 - 不一定是这样。例如,我创建了一个主题,并查看了日志和索引的内容。

****000---180.index文件的内容是****(在此处观察偏移量 -按顺序增加):

offset: 217 position: 4107 offset: 254 position: 8214 offset: 291 position: 12321 offset: 328 position: 16428 offset: 365 position: 20535 offset: 402 position: 24642 offset: 439 position: 28749

****000---180.log文件的内容是****(观察这里的偏移量 -依次增加):

[为了方便起见,我使用了 3 个点 (...) 来表示索引中可用的偏移量之间的行]

offset: 217 position: 4107 CreateTime: 1537550091903 isvalid: true keysize: 0 valuesize: 43 magic: 2 compresscodec: NONE producerId: -1 sequence: -1 isTransactional: false headerKeys: [] offset: 218 position: 4218 CreateTime: 1537550092908 isvalid: true keysize: 0 valuesize: 43 magic: 2 compresscodec: NONE producerId: -1 sequence: -1 isTransactional: false headerKeys: [] offset: 219 position: 4329 CreateTime: 1537550093910 isvalid: true keysize: 0 valuesize: 43 magic: 2 compresscodec: NONE producerId: -1 sequence: -1 isTransactional: false headerKeys: [] ... offset: 253 position: 8103 CreateTime: 1537550127960 isvalid: true keysize: 0 valuesize: 43 magic: 2 compresscodec: NONE producerId: -1 sequence: -1 isTransactional: false headerKeys: [] offset: 254 position: 8214 CreateTime: 1537550128961 isvalid: true keysize: 0 valuesize: 43 magic: 2 compresscodec: NONE producerId: -1 sequence: -1 isTransactional: false headerKeys: [] offset: 255 position: 8325 CreateTime: 1537550129962 isvalid: true keysize: 0 valuesize: 43 magic: 2 compresscodec: NONE producerId: -1 sequence: -1 isTransactional: false headerKeys: [] ... offset: 289 position: 12099 CreateTime: 1537550164007 isvalid: true keysize: 0 valuesize: 43 magic: 2 compresscodec: NONE producerId: -1 sequence: -1 isTransactional: false headerKeys: [] offset: 290 position: 12210 CreateTime: 1537550165008 isvalid: true keysize: 0 valuesize: 43 magic: 2 compresscodec: NONE producerId: -1 sequence: -1 isTransactional: false headerKeys: [] offset: 291 position: 12321 CreateTime: 1537550166009 isvalid: true keysize: 0 valuesize: 43 magic: 2 compresscodec: NONE producerId: -1 sequence: -1 isTransactional: false headerKeys: [] offset: 292 position: 12432 CreateTime: 1537550436878 isvalid: true keysize: 0 valuesize: 43 magic: 2 compresscodec: NONE producerId: -1 sequence: -1 isTransactional: false headerKeys: [] ... offset: 327 position: 16317 CreateTime: 1537550471917 isvalid: true keysize: 0 valuesize: 43 magic: 2 compresscodec: NONE producerId: -1 sequence: -1 isTransactional: false headerKeys: [] offset: 328 position: 16428 CreateTime: 1537550472919 isvalid: true keysize: 0 valuesize: 43 magic: 2 compresscodec: NONE producerId: -1 sequence: -1 isTransactional: false headerKeys: [] offset: 329 position: 16539 CreateTime: 1537550473920 isvalid: true keysize: 0 valuesize: 43 magic: 2 compresscodec: NONE producerId: -1 sequence: -1 isTransactional: false headerKeys: []

对于第二个问题

我认为上面的例子应该澄清这一点。是的,索引中的位置反映了段日志文件和分区中的位置。在获取请求的情况下,一旦在二进制搜索中找到最近的偏移量 - 控制就转到段日志中的那个偏移量。

我希望这有帮助!


推荐阅读