天天看點

lucene LZ4 會将doc存儲在一個chunk裡進行Lz4壓縮 ES的_source便如此

預設情況下,Elasticsearch 用 JSON 字元串來表示文檔主體儲存在 <code>_source</code> 字段中。像其他儲存的字段一樣,<code>_source</code> 字段也會在寫入硬碟前壓縮。The _source is stored as a binary blob (which is compressed by Lucene with deflate or LZ4) 其實就是多個_source合并到一個chunk裡進行LZ4壓縮!

 對于Solr來說:Solr4.8.0裡面使用的fdt和fdx的格式是lucene4.1的。為了提升壓縮比,StoredFieldsFormat以16KB為機關對文檔進行壓縮,使用的壓縮算法是LZ4,由于它更着眼于速度而不是壓縮比,是以它能快速壓縮以及解壓。

  具體參考Lucene41StoredFieldsFormat.html (見Lucene4.2.0的docs)

fdt檔案結構:

上圖了解起來也不難,&lt;Header&gt;和PackedIntsVersion略過,我們重點關注&lt;Chunk&gt;,Chunk的中文意思是”大塊”,我們可以了解為資料的存儲區域。在記憶體中表現為緩存。一個Chunk由5個部分組成:DocBase表示目前的Chunk塊的起始DocId;ChunkDocs表示目前Chunk中的doc個數;DocFieldCounts是一個數組,表示每個doc中Field的個數;DocLengths也是一個數組,表示每個doc占用byte的個數,即doc的長度;&lt;CompressedDocs&gt;即doc的内容,用LZ4算法壓縮存儲。FieldNumAndType是把FieldNumber和FieldType合并到一個VLong字段裡面,整個&lt;CompressedDocs&gt;就是FieldNumAndType和Value的交替序列。

   fdx檔案結構:

fdx檔案重點關注的是&lt;Block&gt;,一個Block由三個部分組成:BlockChunks表示目前Block中Chunk的個數;&lt;DocBases&gt;表示目前Block中每個Chunk的doc個數,可以看作一個數組;&lt;StartPointers&gt;表示目前Block中每個Chunk在fdt檔案中的起始位置,其結構與&lt;DocBases&gt;相同。

盡管fdx/fdt檔案隻是Lucene的正向檔案,并不是Lucene的核心。但是還是有幹貨的。在Lucene4中引入了LZ4算法對fdt的doc進行了實時壓縮/解壓。而且用SPI(Service Provider Interface)技術對架構進行了重構。

fdx/fdt檔案的寫入操作非常清晰。邏輯上都在CompressingStoredFieldsWriter類中完成,而CompressingStoredFieldsIndexWriter則作為其成員變量。其寫入的順序與上面的格式一緻,隻是有些名字不一樣。在寫入docs的過程中,用GrowableByteArrayDataOutput作為緩存,直到緩存滿了,才flush到硬碟上去。用LZ4算法壓縮就是在flush時處理的。(關于LZ4算法會在另外的博文中描述)

       fdt檔案的基本機關是Chunk,這一點需要牢記。一個Chunk寫入到檔案中的代碼如下:

       通過觀察flush函數,我們會發現fdt檔案的寫入非常簡單,就兩句代碼:

前面一句代碼記錄整個chunk中的docBase(最小docID),numBufferedDocs(doc數量),numStoredFields(每個doc的Field個數),lengths(每個doc的長度),一共四種資訊.在記錄numStoredFields和lengths時,用PackedInts及其它的方式對内容進行了壓縮。後面一句代碼記錄整個chunk中的doc的完整内容(用LZ4算法進行壓縮).

本文轉自張昺華-sky部落格園部落格,原文連結:http://www.cnblogs.com/bonelee/p/7724285.html,如需轉載請自行聯系原作者

繼續閱讀