lucene的數據域也就是存儲document文檔的區域,只能經過ID號來定位文檔,定位後可根據指定的字段獲取所需數據。粗略的說fdt文件存儲數據,fdx文件用於經過ID號來定位文檔。(注:如下列出的內容只包含關鍵數據結構以及原理部分,由於lucene在設計的時候考慮到各個版本的兼容性問題和數據文件的完整性問題,有興趣的本身直接看源碼吧)算法
lucene在寫入數據的時候是按照數量達到必定閾值或者佔用空間達到必定閾值後批量寫入的,在寫入的過程當中須要記錄該數據塊一共包含的文檔數量、該數據塊的起始文檔編號、每篇文檔的佔用空間以及每篇文檔包含的字段數量,而後將該元數據信息與數據內容經過壓縮算法寫入文件中。在隨機訪問某篇文檔數據的時候,首先須要定位到該文檔所在數據塊的起始文件指針,而後經過解壓算法還原出元數據信息與數據內容,最後經過元數據信息定位到該文檔的指針位置並讀取文檔數據。總體的實現思路就是這樣,其中的實現技巧或者是關鍵技術仍是數據的壓縮問題。數據結構
fdt文件內容以下:.net
分片大小---是預先設定的值設計
文件頭部分指針
文檔起始編號、文檔數量、是否切片、每篇文檔存儲字段的個數、每篇文檔的佔用空間blog
文檔起始編號是在數據塊中的起始的文檔編號,並且是全局的;內存
文檔數量是該數據塊中包含的文檔數,由於在數據塊劃分的條件是(數量達到必定閾值或者佔用空間達到必定閾值),所以塊中包含的數量是個變量,須要記錄下來;文檔
是否切片是指若是數據塊>=2倍的分片大小時就按每數據塊大小進行分片壓縮,目的在於若是隻對文檔的第一個字段感興趣就不用等待整個文檔解壓完畢後進行訪問,只需解壓指定數據塊的大小,提升效率;注意:lucene的單個文檔大小不能大於(1<<31)-分片大小(默認值是1<<14即16KB),緣由就在於切片處理的過程當中會發生整型值溢出問題!get
每篇文檔存儲字段的個數是指lucene在存儲文檔的時候,每篇文檔間的字段能夠互不相同,因此個數也不一樣;源碼
每篇文檔的佔用空間是指每一個文檔實際佔用的字節數;
數據域部分
按照分片大小切分,對數據塊採用LZ4壓縮算法
數據塊具體包括:字段ID、字段類型、字段值,不一樣的字段類型採用不一樣的寫入方式,尤爲是整型值和浮點型的壓縮在結合lucene談談日期的壓縮問題和結合lucene談談浮點數的壓縮問題中也已經提過,有興趣的能夠看看。
分片總個數
就是一共分了多少個數據塊
fdx文件內容以下:
fdx文件的做用在前面已經說過,它實現的關鍵也是如何壓縮數據,進一步減小空間。因爲文件指針是個long類型的值,而且當fdt文件每次flush一個數據塊時就提交一次(極端狀況下是一篇文檔提交一次)通常較大,所以文件指針也是當達到必定數量後進行批量存儲便於進一步壓縮。爲啥要壓縮呢,由於fdx文件是常駐內存的。
該文件也是按照分塊的方式對文件指針批量寫入並壓縮存儲,它須要存儲分塊的個數、每塊每一個分片起始的文檔編號、每一個塊中每一個分片的fdt文件指針,因爲每一個塊中每一個分片中包含文檔的數量與文檔數據佔用空間是很接近的,這裏的壓縮採用了與MonotonicLongValues相似的處理方法即去掉線性趨勢,讓序列平穩化。