kafka将一个partiton分割成很多个segment文件,segment下分为几部分
- index文件:索引文件,与log文件有一定的关联关系
- log文件:真正存储数据的文件
例如:
这是我的topic下一个partition下中segment文件结构(为了方便调试,将segment大小设置为10K,图中包含2个segment:000.和238.)
其文件名的规则如下:
- 同一个segment下,index和log名字相同
- 下一个segment是上一个segment的lastOffset(这个offset后面会说)
index文件有什么用呢?其实就是一个索引,记录了一条消息在log文件中的位置,查找消息的时候先从index获取位置,然后就可以定位到消息在log文件具体哪个地方
index采用了稀疏索引的方式去存储,不是每来一条消息就记录一个索引,而是当消息大于某个值的时候,就会记录一次索引,默认是4KB
那么index是如何工作的,我们举个例子来说明会更加的方便理解,假设segment配置了10KB(log.segment.bytes),每1KB记录一次索引(log.index.interval.bytes参数),topic下只有1个partition,一个消息大小为43
此时发送多个消息,直到发送了24个消息的时候,此时log文件大小为1032,那么大于log.index.interval.bytes指定的值,需要增加索引,此时结构如下:
log文件这时候有24个消息0~23,文件位置为 1032,那么由于每1KB创建一个索引,则这时候index会创建一条索引,分别有两个属性:
- 24:消息在log文件中的位置,可以简单理解为当前是第几个消息
- 1032:当前消息物理偏移量
当发送了238个消息后,这时log文件的大小为10234,由于配置的segment大小为10KB(10240),那么就是说,当下一个消息过来,必须要新建segment文件,这时的文件转化如下:
文件名以238结尾,这个238即为上一个segment文件最后一个消息的offset
这时候索引建立过程和第一个segment一样
注意:index文件计算message在log中的位置的公式为offset-baseOffset
offset代表全局的message数,baseOffset为相对数量(即上面第二个segmemnt就为238),那么相减后,index文件内容就和第一个segment一样了
总结一下segment的命名格式:
0000.log/index:存储第1条message到第238条message
0238.log/index:存储第239条message到第476条message,以上一个segment最后一条message的offset作为文件名
以此类推