為什么需要段合并
性能上 - 提高查詢效率
新增的文檔(addDocument)會(huì)緩存在內(nèi)存索引結(jié)構(gòu)中,在主動(dòng)調(diào)用commit或者定時(shí)自動(dòng)commit時(shí),會(huì)將所有內(nèi)存的緩存數(shù)據(jù)flush到磁盤(pán)生成新segment段文件(每個(gè)segment是一個(gè)獨(dú)立的倒排索引),這樣可能會(huì)導(dǎo)致短時(shí)間內(nèi)的段數(shù)量暴增,每一個(gè)段文件都會(huì)消耗文件句柄、內(nèi)存和cpu運(yùn)行周期等資源。
更重要的是,每個(gè)搜索請(qǐng)求都必須輪流檢查每個(gè)段文件然后匯總查詢結(jié)果,所以段越多,搜索也就越慢。段數(shù)目越少,段文件遍歷和查詢結(jié)果匯總的開(kāi)銷越小;而且因?yàn)樗饕龜?shù)目少,存儲(chǔ)索引元數(shù)據(jù)的信息也少,使磁盤(pán)占用率得到提高。
假如每次addDocument后都調(diào)用commit,那么生成的新segment僅包含一個(gè)文檔,這樣新增N個(gè)文檔會(huì)導(dǎo)致新生成N個(gè)segment段文件,如果是每k次addDocument后才調(diào)用commit,那么新增n個(gè)文檔會(huì)導(dǎo)致新生成n/k個(gè)segment段文件,可見(jiàn)進(jìn)行適量的文檔緩存是必要的。
但是段文件數(shù)目越小,尺寸越大就越高效嗎?也不一定,段文件本質(zhì)上是一個(gè)索引,索引尺寸太大不僅可能使性能退化,而且還有內(nèi)存占用大、加載時(shí)間長(zhǎng)、更新代價(jià)高等等問(wèn)題,所以結(jié)論是:1.Segment段文件應(yīng)當(dāng)保持在適當(dāng)大?。ň唧w大小值可能和內(nèi)存大小、索引類型、磁盤(pán)性能等有關(guān)); 2.盡可能減小段文件數(shù)目。這樣就需要我們不斷進(jìn)行段文件的合并,使的每個(gè)段文件大小較為均衡,以盡可能減少數(shù)目。
功能上 - 支持文檔刪除
機(jī)械硬盤(pán)的隨機(jī)讀寫(xiě)性能差,順序讀寫(xiě)性能高,所以索引文件的操作都盡可能使用順序讀寫(xiě),這樣無(wú)論是在索引加載還是在索引寫(xiě)入時(shí),都能保證高性能。
段文件是基于磁盤(pán)的索引文件,因?yàn)榇疟P(pán)的隨機(jī)定位性能差,所以索引文件的更新、刪除和修改都比較低效,因此段文件一經(jīng)生成就不再修改,所有的文檔變更都是通過(guò)生成新段文件來(lái)實(shí)現(xiàn)。
段合并的時(shí)候會(huì)將那些舊的已刪除文檔 從文件系統(tǒng)中清除。 被刪除的文檔(或被更新文檔的舊版本)不會(huì)被拷貝到新的大段中,一旦合并結(jié)束,新的段被flush到了磁盤(pán),老的段被刪除。
注意:合并大的段需要消耗大量的I/O和CPU資源,可能會(huì)影響搜索性能,因此通常需要限制合并的頻率。
段文件不可變的優(yōu)缺點(diǎn)
段文件生成后是不可修改的,這個(gè)性質(zhì)的優(yōu)點(diǎn)有:
不需要鎖。
不存在寫(xiě)操作就不需要擔(dān)心多進(jìn)程同時(shí)修改數(shù)據(jù)的問(wèn)題。Linux文件系統(tǒng)會(huì)將讀取過(guò)的文件緩存到內(nèi)存中,由于文件不變,只要文件系統(tǒng)緩存中還有足夠的空間,那么大部分讀請(qǐng)求會(huì)直接請(qǐng)求內(nèi)存,而不會(huì)命中磁盤(pán)。這提供了很大的性能提升。(這塊有點(diǎn)疑問(wèn),支持修改就不能充分利用系統(tǒng)緩沖?)
段文件可以在寫(xiě)入磁盤(pán)前進(jìn)行充分壓縮,能夠有效減少磁盤(pán)I/O和需要被緩存到內(nèi)存的索引的數(shù)據(jù)量。
缺點(diǎn)有:
- 文檔修改(更新)和刪除必須通過(guò)重建索引來(lái)實(shí)現(xiàn),這對(duì)文檔更新/刪除的實(shí)時(shí)性造成了很大的限制。
- 其他