本文使用Lucene代码版本: 8.7.0
前言
首先学习一下lucene的索引文件结构. 本文介绍 Field 相关信息的存储文件格式.
当你在写入field信息时,如果像下面这样, 指定了Stored. 也就是希望lucene 能够保存你的原始Field信息,那么就会生成三个文件 .fdt .fdm .fdx.
其中
- .fdt 文件保存了原始的field信息
- .fdx 文件保存了一些帮助读取fdt的索引信息
- .fdm 文件保存了一些基本的元数据,也包括一些辅助读取fdx文件的信息.
本文首先介绍fdm的文件格式, 及学习一下其在Lucene8.7.0中的写入相关代码.
.fdm文件整体结构
- IndexHeader 索引文件头 lucene 对于索引文件,会写一个文件头,来标识一些基本的数据.
包含:
- CodecHeader: 一个编码的Header.
- SegmentID: 当前Segment的ID, 随机生成的16位字符串
- SegmentSuffix: 当前Segment的后缀
- Magic: 一个魔法数字,永远是: 0x3fd76c17.
- CodecName: 当前编码的名字, 比如对于当前的fdm文件时: “Lucene85FieldsIndexMeta”
- Version: 一个内部的版本号, 不是lucene版本号哦.
- ChunSize 每个Chunk中的doc数量
- Version 版本号
- NumDocs: doc数量的总数
- BlockShift: 控制chunk信息写入时的分块, 2 ^ blockShift 为一块.
- totalChunks: 总共有多少个chunk
- ChunkDocsNumIndex: 存储每个chunk中doc数量的内容, 在fdx文件中的起始偏移位置
- ChunksDocsNumMeta: fdx文件中存储Chunk中doc数量, 用到的一些元数据
在fdx文件中, 存储每个chunk中的doc数量时, 使用了DirectMonotonicWriter
类来进行存储, 这个类用来存储单调递增数组,能够进行一些压缩.具体的别的文章中详细说~
为了完成压缩的功能, 需要一些数字进行辅助,就是下面这几位咯.
代码语言:javascript复制- Min : 通过编码计算的最小值
- AvgInc: 通过编码计算的平均斜率
- ChunDocsNumIndex: 从开始写入到现在, fdx文件的偏移量
- BitRequired: 所有要写入的数字, 最大需要多少位才能存储
- ChunkStartIndex: 存储
每个chunk数据起始位置
数据的起始位置 - ChunkStartPointMeta: 存储每个chunk数据起始位置的一些元数据
在储存每个chunk的数据在fdx文件中的起始位置
的相关数据时, 和上面的chunk内doc数量一样, 做了一些压缩~
- Min : 通过编码计算的最小值
- AvgInc: 通过编码计算的平均斜率
- ChunDocsNumIndex: 从开始写入到现在, fdx文件的偏移量
- BitRequired: 所有要写入的数字, 最大需要多少位才能存储
- StartPointEndPoint: 存储
每个chunk数据起始位置
的数据的结束位置. - MaxPoint: fdx的最大写入位置
- numDirtyChunks: 脏的chunk的数量, 当chunk并没有到达数量,而是强行进行finish,那么相关的chunk和doc就是dirty的. 这两个变量记录了一下相关的数量.
- numDirtyDocs: 脏的doc的数量
- footer: 索引文件的脚部
知其然知其所以然
每个字段, 每段数据, 是为什么存储, 其实我不太知道. 目前看的代码还不是很多.
但是我们应该知道, 所以我罗列在这里,不知道的后来补上~
数据/字段名 | 内容 | 作用 |
---|---|---|
IndexHeader | 索引文件header | 为了标识一些基础信息,也可以用来做一些文件的验证. |
ChunSize | 每个chunk包含多少个doc | chunk是固定大小的,在创建时会初始化,因此可以方便的按chunk进行读取,索引等. |
Version | 内部版本号 | 不知道. |
NumDocs | 当前文件的总数 | 计数用. |
BlockShift | 多少chunk的数据进行一个block存储 | 对chunk的数据进行分块存储用 |
totalChunks | 总共有多少个chunk | 计数用. |
ChunkDocsNumIndex | 存储每个chunk中doc数量的内容, 在fdx文件中的起始偏移位置 | 方便读取fdx文件 |
ChunksDocsNumMeta | fdx文件中存储Chunk中doc数量, 用到的一些元数据 | fdx文件对数据进行压缩,压缩用的一些配合型的数据 |
Min | 通过编码计算的最小值 | 记录最小的数字,具体作用在DirectMonotonicWriter中详细解释 |
AvgInc | 通过编码计算的平均斜率 | DirectMonotonicWriter |
ChunDocsNumIndex | 从开始写入到现在, fdx文件的偏移量 | DirectMonotonicWriter |
BitRequired | 所有要写入的数字, 最大需要多少位才能存储 | DirectMonotonicWriter |
ChunkStartIndex | 存储每个chunk数据起始位置的位置 | 方便读取fdx文件 |
ChunkStartPointMeta | 存储每个chunk数据起始位置的一些元数据 | 同上 |
StartPointEndPoint | 存储每个chunk数据起始位置的数据的结束位置 | 同上 |
MaxPoint | fdx的最大写入位置 | 同上 |
numDirtyChunks | 脏的chunk的数量 | 不确定 |
numDirtyDocs | 脏的doc的数量 | 不确定 |
footer | 索引文件的脚部 | 用来表示文件结束,同时里面含有CRC32来check文件数据是否正确. |
相关代码分析
在8.7.0版本, 对Field相关信息的存储在org.apache.lucene.codecs.compressing.CompressingStoredFieldsWriter
类中.
首先, 在类构造函数中, 进行了fdm文件的初始化, 之后写入了IndexHeader. 以及chunkSize
及Version
.
.
之后在程序不断的添加Document过程中, 不再写入fdm文件,在所有Document全部写入之后,会调用 org.apache.lucene.codecs.compressing.CompressingStoredFieldsWriter#finish
方法, 在该方法中, 写入了部分数据.
如上图所示, 在1处写入了fdm配合fdx文件的一些元数据. 在2处写入了numDirtyChunks,numDirtyDocs及Footer
.
在1处,配合fdx文件写入了些什么呢?
在3处, 写入了numDocs, blockShift, totalChunks, filePoint
等信息. 这些都是顺序的, 和前方的整体格式图一一对应.
比较麻烦的是, 在上图中4处, 在fdx文件存储所有chunk中doc数量时, 应用了DirectMonotonicWriter
类来进行存储, 该类的具体实现可以阅读延伸阅读中的文章.DirectMonotonicWriter源码分析
该类大致做了什么呢?
- 所有chunk的doc数量.
- 所有chunk具体信息存储的point.
这两个数组都是单调递增的, 因此DirectMonotonicWriter
类就是专门用来存储单调递增数组的. 根据单调递增这个因素, 对传入的int数组进行了压缩,压缩中用到了几个参数, 在之后复原数据时需要. 那就是Min,AvgInc,Offset,BitRequired
. 这里使用了fdm文件来存储这几个参数而已.
延伸阅读
DirectMonotonicWriter
类的原理解析. 具体文章还没写哈哈哈.
参考文章
https://www.amazingkoala.com.cn/Lucene/suoyinwenjian/2020/1013/169.html
完。
联系我
最后,欢迎关注我的个人公众号【 呼延十 】,会不定期更新很多后端工程师的学习笔记。 也欢迎直接公众号私信或者邮箱联系我,一定知无不言,言无不尽。
以上皆为个人所思所得,如有错误欢迎评论区指正。
欢迎转载,烦请署名并保留原文链接。
联系邮箱:huyanshi2580@gmail.com
更多学习笔记见个人博客或关注微信公众号 <呼延十 >——>呼延十
var gitment = new Gitment({ id: 'Lucene系列(五)索引格式之fdm文件', // 可选。默认为 location.href owner: 'hublanker', repo: 'blog', oauth: { client_id: '2297651c181f632a31db', client_secret: 'a62f60d8da404586acc965a2ba6a6da9f053703b', }, }) gitment.render('container')
- Previous Lucene系列(四)directmonotonicwriter源码分析
- Next Lucene系列(六)索引格式之fdt文件