ES近實時搜索原理

關(guān)系圖:
image.png

Segment(段):Lucene里面的一個數(shù)據(jù)集概念
提交點文件:有一個列表存放著所有已知的所有段
ES底層是基于Lucene,最核心的概念就是Segment(段),每個段本身就是一個倒排索引。
ES中的Index由多個段的集合和commit point(提交點)文件組成。

提交點文件中有一個列表存放著所有已知的段,下面是一個帶有1個提交點和3個段的Index示意圖:


image.png

Doc新增提交主要過程如下:
一、寫入磁盤后可見:
1、Doc寫入Buffer
Doc會先被搜集到內(nèi)存中的Buffer內(nèi),這個時候還無法被搜索到,如下圖所示:


image.png

2、 Doc Commit
每隔一段時間,會將buffer提交,在flush磁盤后打開新段使得搜索可見,詳細(xì)過程如下:

(1)創(chuàng)建一個新段,作為一個追加的倒排索引,寫入到磁盤(文件系統(tǒng)緩存)
(2)將新的包含新段的Commit Point(提交點)寫入磁盤(文件系統(tǒng)緩存)
(3)磁盤進(jìn)行fsync,主要是將文件系統(tǒng)緩存中等待的寫入操作全部物理寫入到磁盤,保證數(shù)據(jù)不會在發(fā)生錯誤時丟失
(4)這個新的段被開啟, 使得段內(nèi)文檔對搜索可見
(5)將內(nèi)存中buffer清除,又可以把新的Doc寫入buffer了
下面展示了這個過程完成后的段和提交點的狀態(tài):


image.png

通過這種方式,可以使得新文檔從被索引到可被搜索間的時間間隔在數(shù)分鐘,但是還不夠快。因為磁盤需要fsync,這個就成為性能瓶頸。我們前面提到過Doc會先被從buffer刷入段寫入文件系統(tǒng)緩存(很快),那么就自然想到在這個階段就讓文檔對搜索可見,隨后再被刷入磁盤(較慢)。
二、寫入磁盤前可見:
ES寫入原理流程圖.png

Commits in Lucene

為了數(shù)據(jù)安全,每次的索引變更都最好要立刻刷盤, 所以 Commit 操作意味著將Segment 合并并寫入磁盤。保證內(nèi)存數(shù)據(jù)盡量不丟。刷盤是很重的 IO 操作, 所以為了機(jī)器性能和近實時搜索, 并不會刷盤那么及時。

Translog

新文檔被索引意味著文檔會被首先寫入內(nèi)存 buffer 和 translog 文件。每個 shard 都對應(yīng)一個 translog 文件。


translog.png

Refresh in Elasticsearch

在 elasticsearch 中, _refresh操作默認(rèn)每秒執(zhí)行一次,意味著將內(nèi)存 buffer 的數(shù)據(jù)寫入到一個新的Segment 中,這個時候索引變成了可被檢索的。


refresh.png

Flush in Elasticsearch

Flush操作意味著將內(nèi)存buffer的數(shù)據(jù)全都寫入新的Segments中,并將內(nèi)存中所有的Segments全部刷盤,并且清空translog日志的過程。


flush.png

1、refresh:
Lucene支持對新段寫入和打開 - 可以使文檔在沒有完全刷入硬盤的狀態(tài)下就能對搜索可見,而且是一個開銷較小的操作,可以頻繁進(jìn)行。
下面是一個已經(jīng)將Docs刷入段但還沒有完全提交的示意圖:


image.png

我們可以看到,新段雖然還沒有被完全提交,但是已經(jīng)對搜索可見了。
這種對新段的巧妙操作過程被稱為refresh,默認(rèn)執(zhí)行的時間間隔是1秒,這就是ES被稱為近實時搜索的原因。

2、translog
為了避免在兩次commit操作間隔時間發(fā)生異常導(dǎo)致Doc丟失,ES中采用了一個事務(wù)日志記錄每次對ES的操作。加上translog后新增文檔流程如下:
文檔被添加到buffer同時追加到translog,如圖:


image.png

進(jìn)行refresh操作,清空buffer,文檔可被搜索但尚未flush到磁盤。translog不會清空,如圖:
image.png

繼續(xù)步驟1的過程:
每隔一段時間(例如translog變得太大),index會被flush到磁盤,新的translog文件被創(chuàng)建,這個commit完整執(zhí)行結(jié)束。在這個操作后,會發(fā)生以下事件:
(1)所有內(nèi)存中的buffer會被寫入新段
(2)buffer被清空
(3)一個提交點被寫入磁盤
(4)文件系統(tǒng)緩存通過fsync flush
(5)之前的舊translog被刪除

下面示意圖展示了這個狀態(tài):


image.png

3、translog的作用
(1)通過前文描述我們知道translog其實就記錄了還尚未被flush到磁盤的操作。當(dāng) Elasticsearch 啟動的時候, 它會從磁盤中使用最后一個提交點去恢復(fù)已知的段,并且會重放 translog 中所有在最后一次提交后發(fā)生的變更操作。
translog 也被用來提供實時 CRUD 。當(dāng)你試著通過ID來RUD一個Doc,它會在從相關(guān)的段檢索之前先檢查 translog 中最新的變更。
(2)translog的安全性
默認(rèn)translog是每5秒或是每次請求完成后被fsync到磁盤(在主分片和副本分片都會)。也就是說,如果你發(fā)起一個index, delete, update請求寫入translog并被fsync到主分片和副本分片的磁盤前不會返回200狀態(tài)。
這樣會帶來一些性能損失,可以通過設(shè)為異步fsync,但是必須接受由此帶來的丟失少量數(shù)據(jù)的風(fēng)險:
PUT /my_index/_settings
{
    "index.translog.durability": "async",
    "index.translog.sync_interval": "5s"
}

4、flush
flush就是執(zhí)行commit清空、干掉老translog的過程。默認(rèn)每個分片30分鐘或者是translog過于大的時候自動flush一次??梢酝ㄟ^flush API手動觸發(fā),但是只會在重啟節(jié)點或關(guān)閉某個索引的時候這樣做,因為這可以讓未來ES恢復(fù)的速度更快(translog文件更小)。
三、 ES對Doc刪除的處理
(1)刪除一個ES文檔不會立即從磁盤上移除,它只是被標(biāo)記成已刪除。因為段是不可變的,所以文檔既不能從舊的段中移除,舊的段也不能更新以反映文檔最新的版本。
ES的做法是,每一個提交點包括一個.del文件(還包括新段),包含了段上已經(jīng)被標(biāo)記為刪除狀態(tài)的文檔。所以,當(dāng)一個文檔被做刪除操作,實際上只是在.del文件中將該文檔標(biāo)記為刪除,依然會在查詢時被匹配到,只不過在最終返回結(jié)果之前會被從結(jié)果中刪除。ES將會在用戶之后添加更多索引的時候,在后臺進(jìn)行要刪除內(nèi)容的清理。
(2)Doc刪除與段合并的關(guān)系
通過每秒自動刷新創(chuàng)建新的段,用不了多久段的數(shù)量就爆炸了,每個段消費(fèi)大量文件句柄,內(nèi)存,cpu資源。更重要的是,每次搜索請求都需要依次檢查每個段。段越多,查詢越慢。
ES通過后臺合并段解決這個問題。ES利用段合并的時機(jī)來真正從文件系統(tǒng)刪除那些version較老或者是被標(biāo)記為刪除的文檔。被刪除的文檔(或者是version較老的)不會再被合并到新的更大的段中。
ES對一個不斷有數(shù)據(jù)寫入的索引處理流程如下:
索引過程中,refresh會不斷創(chuàng)建新的段,并打開它們。
合并過程會在后臺選擇一些小的段合并成大的段,這個過程不會中斷索引和搜索。合并過程如圖:


image.png

兩個已提交的段 和一個未提交的段合并為一個更大的段。從上圖可以看到,段合并之前,舊有的Commit和沒Commit的小段皆可被搜索。
(3)段合并后的操作:
a、新的段flush到硬盤
b、編寫一個包含新段的新提交點,并排除舊的較小段。
c、新的段打開供搜索
d、舊的段被刪除
合并完成后新的段可被搜索,舊的段被刪除,如下圖所示:


image.png

四、Doc更新
文檔的更新操作和刪除是類似的:當(dāng)一個文檔被更新,舊版本的文檔被標(biāo)記為刪除,新版本的文檔在新的段中索引。該文檔的不同版本都會匹配一個查詢,但是較舊的版本會從結(jié)果中刪除。

注:
什么情況下要強(qiáng)制刷新:
1、reindex后,手動修改refresh,由-1(不刷新)改為想要的刷新值
2、在讀多,寫少時,可以強(qiáng)制不刷新,因為每寫入一條數(shù)據(jù)就會產(chǎn)生一個新段,查詢時就會查一次,降低效率
3、即時性要求高,:如廣告立馬需要被看到,需要手動強(qiáng)制刷新

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容