Elasticsearch的存儲(chǔ)模型和讀寫操作

1、辨析Elasticsearch的索引和Lucence的縮影

Elasticsearch中的索引是組織數(shù)據(jù)的邏輯空間(好比數(shù)據(jù)庫(kù))。一個(gè)Elasticsearch索引有一個(gè)或者多個(gè)分片(默認(rèn)是5個(gè))。分片對(duì)應(yīng)實(shí)際存儲(chǔ)數(shù)據(jù)的Lucence索引,分片自身就是一個(gè)搜索引擎。每個(gè)分片有一個(gè)或者多個(gè)副本(默認(rèn)是1個(gè)副本)。Elasticsearch中還包含'type'(數(shù)據(jù)中的table),用于邏輯上隔離索引中存儲(chǔ)的數(shù)據(jù)。在Elasticsearch中,給定一個(gè)type,它的所有文檔都會(huì)擁有相同的屬性(table的schema).


圖a展示了一個(gè)包含3個(gè)分片的Elasticsearch索引,每個(gè)分片擁有1個(gè)副本。這些分片組成了一個(gè)Elasticsearch索引,每個(gè)分片自身是一個(gè)Lucene索引。

圖b展示了Elasticsearch索引、分片、Lucene索引和文檔之間的邏輯關(guān)系。

對(duì)應(yīng)于關(guān)系數(shù)據(jù)庫(kù)術(shù)語(yǔ)

Elasticsearch Index == Database

Types == Tables

Properties == Schema

2 節(jié)點(diǎn)類型

一個(gè)Elasticsearch實(shí)例是一個(gè)節(jié)點(diǎn),一組節(jié)點(diǎn)組成了集群。Elasticsearch集群中的節(jié)點(diǎn)可以配置為3種不同的角色:

主節(jié)點(diǎn):控制Elasticsearch集群,負(fù)責(zé)集群中的操作,比如創(chuàng)建/刪除一個(gè)索引,跟蹤集群中的節(jié)點(diǎn),分配分片到節(jié)點(diǎn)。主節(jié)點(diǎn)處理集群的狀態(tài)并廣播到其他節(jié)點(diǎn),并接收其他節(jié)點(diǎn)的確認(rèn)響應(yīng)。

每個(gè)節(jié)點(diǎn)都可以通過(guò)設(shè)定配置文件elasticsearch.yml中的node.master屬性為true(默認(rèn))成為主節(jié)點(diǎn)。

對(duì)于大型的生產(chǎn)集群來(lái)說(shuō),推薦使用一個(gè)專門的主節(jié)點(diǎn)來(lái)控制集群,該節(jié)點(diǎn)將不處理任何用戶請(qǐng)求。

數(shù)據(jù)節(jié)點(diǎn):持有數(shù)據(jù)和倒排索引。默認(rèn)情況下,每個(gè)節(jié)點(diǎn)都可以通過(guò)設(shè)定配置文件elasticsearch.yml中的node.data屬性為true(默認(rèn))成為數(shù)據(jù)節(jié)點(diǎn)。如果我們要使用一個(gè)專門的主節(jié)點(diǎn),應(yīng)將其node.data屬性設(shè)置為false。

客戶端節(jié)點(diǎn):如果我們將node.master屬性和node.data屬性都設(shè)置為false,那么該節(jié)點(diǎn)就是一個(gè)客戶端節(jié)點(diǎn),扮演一個(gè)負(fù)載均衡的角色,將到來(lái)的請(qǐng)求路由到集群中的各個(gè)節(jié)點(diǎn)。

Elasticsearch集群中作為客戶端接入的節(jié)點(diǎn)叫協(xié)調(diào)節(jié)點(diǎn)。協(xié)調(diào)節(jié)點(diǎn)會(huì)將客戶端請(qǐng)求路由到集群中合適的分片上。對(duì)于讀請(qǐng)求來(lái)說(shuō),協(xié)調(diào)節(jié)點(diǎn)每次會(huì)選擇不同的分片處理請(qǐng)求,以實(shí)現(xiàn)負(fù)載均衡。

在我們開(kāi)始研究發(fā)送給協(xié)調(diào)節(jié)點(diǎn)的CRUD請(qǐng)求是如何在集群中傳播并被引擎執(zhí)行之前,讓我們先來(lái)看一下Elasticsearch內(nèi)部是如何存儲(chǔ)數(shù)據(jù),以支持全文檢索結(jié)果的低延遲服務(wù)的。

存儲(chǔ)模型

Elasticsearch使用了Apache Lucene,后者是Doug Cutting(Apache Hadoop之父)使用Java開(kāi)發(fā)的全文檢索工具庫(kù),其內(nèi)部使用的是被稱為倒排索引的數(shù)據(jù)結(jié)構(gòu),其設(shè)計(jì)是為全文檢索結(jié)果的低延遲提供服務(wù)。文檔是Elasticsearch的數(shù)據(jù)單位,對(duì)文檔中的詞項(xiàng)進(jìn)行分詞,并創(chuàng)建去重詞項(xiàng)的有序列表,將詞項(xiàng)與其在文檔中出現(xiàn)的位置列表關(guān)聯(lián),便形成了倒排索引。

這和一本書后面的索引非常類似,即書中包含的詞匯與其出現(xiàn)的頁(yè)碼列表關(guān)聯(lián)。當(dāng)我們說(shuō)文檔被索引了,我們指的是倒排索引。我們來(lái)看下如下2個(gè)文檔是如何被倒排索引的:

文檔1(Doc 1): Insight Data Engineering Fellows Program

文檔2(Doc 2): Insight Data Science Fellows Program


如果我們想找包含詞項(xiàng)"insight"的文檔,我們可以掃描這個(gè)(單詞有序的)倒排索引,找到"insight"并返回包含改詞的文檔ID,示例中是Doc 1和Doc 2。

創(chuàng)建(Create)

Elasticsearch集群中每個(gè)節(jié)點(diǎn)都包含 了該節(jié)點(diǎn)上分片的元數(shù)據(jù)信息。協(xié)調(diào)節(jié)點(diǎn)(默認(rèn))使用ID參與計(jì)算,以便為路由提供合適的分片。Elasticsearch使用MurMurHash3函數(shù)對(duì)文檔ID進(jìn)行Hash,其結(jié)果再對(duì)分片數(shù)量取模,得到的結(jié)果即是索引文檔的分片

shard = hash(document_id) % (num_of_primary_shards)

1、當(dāng)分片所在的節(jié)點(diǎn)接收到來(lái)自協(xié)調(diào)節(jié)點(diǎn)的請(qǐng)求后,會(huì)將該請(qǐng)求寫入translog。并將文檔加入內(nèi)存緩沖(buffer)。如果請(qǐng)求在主分片上成功處理,該請(qǐng)求會(huì)并行發(fā)送的該分片副本上后,客戶端才會(huì)收到確認(rèn)通知。

2、內(nèi)存緩沖會(huì)被周期性刷新(默認(rèn)是1秒),內(nèi)容將被寫到文件系統(tǒng)緩存的一個(gè)新段上。雖然這個(gè)段并沒(méi)有被同步(fsync),但它是開(kāi)放的,內(nèi)容可以被搜索到。

3、每30分鐘,或者translog很大的時(shí)候,translog會(huì)被清空,文件系統(tǒng)緩存會(huì)被同步。這個(gè)過(guò)程在Elasticsearch中稱為沖洗(flush)。在沖洗的過(guò)程中,內(nèi)存中的緩存將被清除,內(nèi)容被寫入一個(gè)新的段,段的fsync將創(chuàng)建一個(gè)新的提交點(diǎn),并將內(nèi)容刷新到磁盤。舊的translog將被刪除并開(kāi)始一個(gè)全新的translog。

shard = hash(document_id) % (num_of_primary_shards)


更新(U)update 和刪除(D)delete

刪除和更新也都是寫操作,但是在Elasticsearch中的文檔時(shí)不可變的,因此刪除或者改動(dòng)以展示其變更;

磁盤上每個(gè)段都有一個(gè)相應(yīng)的.del文件。當(dāng)刪除請(qǐng)求發(fā)送后,文檔并沒(méi)有真的刪除,而是在.del文件中被標(biāo)記為刪除。該文檔仍然能匹配查詢,但是在結(jié)果中被過(guò)濾掉。當(dāng)段合并時(shí),在.del文件中被標(biāo)記為刪除的文件不寫入新段。

查詢階段

查詢階段協(xié)調(diào)節(jié)點(diǎn)會(huì)將查詢請(qǐng)求路由到索引的全部分片(主分片或者副本分片)上。每個(gè)分片獨(dú)立執(zhí)行查詢,并為查詢結(jié)果創(chuàng)建一個(gè)優(yōu)先隊(duì)列,以相關(guān)性得分排序。會(huì)有很多文檔匹配結(jié)果,但是默認(rèn)情況下,每個(gè)分片只發(fā)送前10個(gè)結(jié)果給協(xié)調(diào)節(jié)點(diǎn),協(xié)調(diào)節(jié)點(diǎn)為全部分片上的這些結(jié)果創(chuàng)建優(yōu)先隊(duì)列并返回前10個(gè)作為hit.

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

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

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