lucene內部的合併策略

2021-08-31 12:01:42 字數 3157 閱讀 1164

solr(or lucene)內部的合併策略是怎樣的呢?

選擇哪些段(segment)需要被合併,是基於名為[color=gray]mergepolicy[/color]的抽象類決定的。這個類建立了乙個合併規則類[color=gray]mergespecification[/color]:由[color=gray]onemerge[/color]物件組成的乙個列表集合。其中的每乙個代表了乙個單獨的合併操作;被指定的所有段都將被合併為乙個新的段。

在索引改變之後,[color=gray]indexwriter[/color]會呼叫[color=gray]mergepolicy[/color]來獲取乙個[color=gray]mergespecification[/color];然後開始呼叫[color=gray]mergescheduler[/color],該類負責合併任務的執行。[color=gray]mergescheduler[/color]主要有兩個實現類:[color=gray]concurrentmergescheduler[/color]為並行合併的執行緒類(多執行緒),[color=gray]serialmergescheduler[/color]則會將所有的合併操作在當前執行緒進行(單執行緒)。當合併的時間到了,[color=gray]indexwriter[/color]會將合併的任務交給[color=gray]segmentmerger[/color]來做。

[color=gray]mergepolicy[/color]有很多的實現,我們來看一下它的預設實現類[color=gray]logbytesizemergepolicy[/color]。[color=gray]mergepolicy[/color]定義了三個抽象方法來構造[color=gray]mergespecification[/color]:

1. findmerges() 將會在索引被改變時被呼叫

2. findmergesforoptimize() 在optimize操作時被呼叫

3. findmergestoexpungedeletes() 在刪除操作時被呼叫

step by step

下面先對合併策略作乙個簡短的概念性描述,請看下圖:

1. 將段按name排序

2. 將已存在的段分組(level),每個組(level)都是連續段的集合

3. 對於每個組,確定將要被合併的段

[img]

parameters

下面來說明一下在合併索引時需要用到的一些引數:

1. mergefactor: 這個引數有多種含義,比如有多少段將被合併為新段;每個組的最大段數和每個段的跨度,可以在solrconfig.xml裡設定

2. minmergesize:小於該值的所有段將會被歸於乙個組中,固定值

3. maxmergesize:大於該值的所有段將不會被合併,固定值

4. maxmergedocs:所有文件數大於該值的段將不會被合併,以上引數均在solrconfig.xml中定義

constructing the levels

讓我們看一下組(level)是如何被構造的。為確定第乙個組,演算法會查詢最大合併段大小,我們叫它levelmaxsize。如果這個值小於minmergesize,那麼所有的段都會被歸為乙個組。否則,levelmaxsize的值將為:

[img]

這個演算法的大致含義為:levelmaxsize的值大約為levelmaxsize除以mergefactor的0.75次方(如果1被使用則替代0.75),但是如果算出的值小於minmergesize,則用minmergesize代替。

通過這個計算,演算法將會選擇哪些段屬於當前的組。首先,它講找乙個大於或等於levelminsize的段,如果其他舊的段都比它小,則被歸為乙個組。下乙個組也會使用相同的方式,但是會找比上乙個段更新的段作為比較段。

下面舉個例子,設mergefactor=10 and minmergesize=1.6mib.

[img]

首先取第乙個段200m,得出levelmaxsize為36m,那麼只有i比它大;分為一組,繼續選擇8.9m得出levelmaxsize為1.6m,計算後與6.5m分為一組……

但是,如果你不了解演算法本身,它會構造出你無法預料的組。舉個例子,下面的表中,依然設定mergefactor=10 and minmergesize=1.6mib.

segment 	size

a 200 mib

l 88 mib

m 8.9 mib

n 6.5 mib

o 1.4 mib

p 842 kib

q 842 kib

r 842 kib

s 842 kib

t 842 kib

u 842 kib

v 842 kib

w 842 kib

x 160 mib

會有多少組呢?來看一下:最大的段大小為200m,則levelminsize為36m;最新的比levelminsize 大的段是x,所以第乙個組包括x並且所有的段都比它舊。那麼,這將只有乙個組!

choosing which segments to merge

在定義完組之後,[color=gray]mergepolicy[/color]將會選擇哪些段會被合併:單獨的分析每個組,如果乙個組小於mergefactor 個段,那麼該組會被忽略(不合併)。否則,所有在該組中的段都將被合併為乙個新的段;如果組中有大於maxmergefactor或maxmergedocs的段,則該段被忽略。

回到第2個例子中,當只有一組段需要合併時,合併結果為:

segment 	size

u 842 kib

v 842 kib

w 842 kib

x 160 mib

y 311 mib

minmergesize and maxmergesize

這個說說這兩個引數。目前這兩個值在lucene中是硬編碼的,他們的值為:

minmergesize:1.6m 所有比1.6m小的段都將被歸為1組

maxmergesize:2g 所有大於2g的段都不會再被合併

conclusion

其實這個演算法並不複雜,如果想知道在你的索引新增多個文件時發生了什麼,了解其內部機制是有必要的。同時,了解合併策略是如何工作的,更能幫助你設定一些引數的值(如mergefactor和maxmergedocs)。

lucene索引合併

lucene 索引合併 關鍵步驟如下 indexwriter fswriter null fs indexwriter ramwriter null ram directory fsdir directory ramdir ramdir new ramdirectory 判斷原索引檔案是否存在 開啟...

lucene 索引合併問題

lucene 索引合併 關鍵步驟如下 indexwriter fswriter null fs indexwriter ramwriter null ram directory fsdir directory ramdir ramdir new ramdirectory 判斷原索引檔案是否存在 開啟...

vue mixins 合併策略

1 data mixins中的data會合併到data中,有衝突的話,data中資料覆蓋mixins中的資料。2 鉤子函式 mixins中的鉤子函式也會執行,先執行mixins中的鉤子函式。3 methods components和directives methods components和dire...