lucene系列(五)索引格式之fdm文件

本文使用 Lucene 代碼版本:8.7.0html

前言

首先學習一下 lucene 的索引文件結構。本文介紹 Field 相關信息的存儲文件格式。java

當你在寫入 field 信息時,若是像下面這樣,指定了 Stored. 也就是但願 lucene 可以保存你的原始 Field 信息,那麼就會生成三個文件 .fdt .fdm .fdx.apache

2021-01-23-18-00-42

其中數組

  • .fdt 文件保存了原始的 field 信息
  • .fdx 文件保存了一些幫助讀取 fdt 的索引信息
  • .fdm 文件保存了一些基本的元數據,也包括一些輔助讀取 fdx 文件的信息。

本文首先介紹 fdm 的文件格式,及學習一下其在 Lucene8.7.0 中的寫入相關代碼。微信

.fdm 文件總體結構

2021-01-23-18-05-13

  • IndexHeader 索引文件頭

lucene 對於索引文件,會寫一個文件頭,來標識一些基本的數據。markdown

2021-01-23-18-35-00

包含:koa

  • 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 數量,用到的一些元數據

2021-01-23-18-50-51

在 fdx 文件中,存儲每一個 chunk 中的 doc 數量時,使用了DirectMonotonicWriter類來進行存儲,這個類用來存儲單調遞增數組,可以進行一些壓縮。具體的別的文章中詳細說~函數

爲了完成壓縮的功能,須要一些數字進行輔助,就是下面這幾位咯。oop

- Min : 經過編碼計算的最小值
- AvgInc: 經過編碼計算的平均斜率
- ChunDocsNumIndex: 從開始寫入到如今,fdx 文件的偏移量
- BitRequired: 全部要寫入的數字,最大須要多少位才能存儲
複製代碼
  • ChunkStartIndex: 存儲每一個 chunk 數據起始位置數據的起始位置
  • ChunkStartPointMeta: 存儲每一個 chunk 數據起始位置的一些元數據

在儲存每一個 chunk 的數據在 fdx 文件中的起始位置的相關數據時,和上面的 chunk 內 doc 數量同樣,作了一些壓縮~源碼分析

2021-01-23-18-54-34

- 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. 以及chunkSizeVersion.

2021-01-24-00-12-04.

以後在程序不斷的添加 Document 過程當中,再也不寫入 fdm 文件,在全部 Document 所有寫入以後,會調用 org.apache.lucene.codecs.compressing.CompressingStoredFieldsWriter#finish 方法,在該方法中,寫入了部分數據。

2021-01-24-00-14-37

如上圖所示,在 1 處寫入了 fdm 配合 fdx 文件的一些元數據。 在 2 處寫入了numDirtyChunks,numDirtyDocs 及 Footer.

在 1 處,配合 fdx 文件寫入了些什麼呢?

2021-01-24-00-19-01

在 3 處,寫入了numDocs, blockShift, totalChunks, filePoint等信息。這些都是順序的,和前方的總體格式圖一一對應。

比較麻煩的是,在上圖中 4 處,在 fdx 文件存儲全部 chunk 中 doc 數量時,應用了DirectMonotonicWriter 類來進行存儲,該類的具體實現能夠閱讀延伸閱讀中的文章。DirectMonotonicWriter 源碼分析

該類大體作了什麼呢?

  • 全部 chunk 的 doc 數量。
  • 全部 chunk 具體信息存儲的 point.

這兩個數組都是單調遞增的,所以DirectMonotonicWriter類就是專門用來存儲單調遞增數組的。 根據單調遞增這個因素,對傳入的 int 數組進行了壓縮,壓縮中用到了幾個參數,在以後復原數據時須要。那就是Min,AvgInc,Offset,BitRequired. 這裏使用了 fdm 文件來存儲這幾個參數而已。

延伸閱讀

DirectMonotonicWriter類的原理解析。具體文章還沒寫哈哈哈。

參考文章

www.amazingkoala.com.cn/Lucene/suoy…


完。

以上皆爲我的所思所得,若有錯誤歡迎評論區指正。

歡迎轉載,煩請署名並保留原文連接。

聯繫郵箱:huyanshi2580@gmail.com

更多學習筆記見我的博客或關注微信公衆號 < 呼延十 >------>呼延十

相關文章
相關標籤/搜索