本篇內(nèi)容主要講解“Elasticsearch的原理是什么”,感興趣的朋友不妨來(lái)看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來(lái)帶大家學(xué)習(xí)“Elasticsearch的原理是什么”吧!
專注于為中小企業(yè)提供成都網(wǎng)站建設(shè)、成都網(wǎng)站設(shè)計(jì)服務(wù),電腦端+手機(jī)端+微信端的三站合一,更高效的管理,為中小企業(yè)貢山免費(fèi)做網(wǎng)站提供優(yōu)質(zhì)的服務(wù)。我們立足成都,凝聚了一批互聯(lián)網(wǎng)行業(yè)人才,有力地推動(dòng)了上千余家企業(yè)的穩(wěn)健成長(zhǎng),幫助中小企業(yè)通過網(wǎng)站建設(shè)實(shí)現(xiàn)規(guī)模擴(kuò)充和轉(zhuǎn)變。
Lucene 和 ES
Lucene
Lucene 是 Elasticsearch所基于的 Java 庫(kù),它引入了按段搜索的概念:
Segment:也叫段,類似于倒排索引,相當(dāng)于一個(gè)數(shù)據(jù)集。
Commit point:提交點(diǎn),記錄著所有已知的段。
Lucene index:“a collection of segments plus a commit point”。由一堆 Segment 的集合加上一個(gè)提交點(diǎn)組成。
對(duì)于一個(gè) Lucene index 的組成,如下圖所示:
ES
一個(gè) Elasticsearch Index 由一個(gè)或者多個(gè) shard(分片)組成。
而 Lucene 中的 Lucene index 相當(dāng)于 ES 的一個(gè) shard。
寫入過程
寫入過程 1.0(不完善)
寫入過程 1.0 如下:
不斷將 Document 寫入到 In-memory buffer(內(nèi)存緩沖區(qū))。
當(dāng)滿足一定條件后內(nèi)存緩沖區(qū)中的 Documents 刷新到磁盤。
生成新的 segment 以及一個(gè) Commit point 提交點(diǎn)。
這個(gè) segment 就可以像其他 segment 一樣被讀取了。
畫圖如下:
將文件刷新到磁盤是非常耗費(fèi)資源的,而且在內(nèi)存緩沖區(qū)和磁盤中間存在一個(gè)高速緩存(cache),一旦文件進(jìn)入到 cache 就可以像磁盤上的 segment 一樣被讀取了。
寫入過程 2.0
寫入過程 2.0 如下:
不斷將 Document 寫入到 In-memory buffer(內(nèi)存緩沖區(qū))。
當(dāng)滿足一定條件后內(nèi)存緩沖區(qū)中的 Documents 刷新到高速緩存(cache)。
生成新的 segment,這個(gè) segment 還在 cache 中。
這時(shí)候還沒有 commit,但是已經(jīng)可以被讀取了。
畫圖如下:
數(shù)據(jù)從 buffer 到 cache 的過程是定期每秒刷新一次。所以新寫入的 Document 最慢 1 秒就可以在 cache 中被搜索到。
而 Document 從 buffer 到 cache 的過程叫做 ?refresh。一般是 1 秒刷新一次,不需要進(jìn)行額外修改。
當(dāng)然,如果有修改的需要,可以參考文末的相關(guān)資料。這也就是為什么說 Elasticsearch 是準(zhǔn)實(shí)時(shí)的。
使文檔立即可見:
PUT /test/_doc/1?refresh {"test": "test"} // 或者 PUT /test/_doc/2?refresh=true {"test": "test"}
Translog 事務(wù)日志
此處可以聯(lián)想 MySQL 的 binlog,ES 中也存在一個(gè) translog 用來(lái)失敗恢復(fù):
Document 不斷寫入到 In-memory buffer,此時(shí)也會(huì)追加 translog。
當(dāng) buffer 中的數(shù)據(jù)每秒 refresh 到 cache 中時(shí),translog 并沒有進(jìn)入到刷新到磁盤,是持續(xù)追加的。
translog 每隔 5s 會(huì) fsync 到磁盤。
translog 會(huì)繼續(xù)累加變得越來(lái)越大,當(dāng) translog 大到一定程度或者每隔一段時(shí)間,會(huì)執(zhí)行 flush。
flush 操作會(huì)分為以下幾步執(zhí)行:
buffer 被清空。
記錄 commit point。
cache 內(nèi)的 segment 被 fsync 刷新到磁盤。
translog 被刪除。
值得注意的是:
translog 每 5s 刷新一次磁盤,所以故障重啟,可能會(huì)丟失 5s 的數(shù)據(jù)。
translog 執(zhí)行 flush 操作,默認(rèn) 30 分鐘一次,或者 translog 太大也會(huì)執(zhí)行。
手動(dòng)執(zhí)行 flush:
POST /my-index-000001/_flush
刪除和更新
segment 不可改變,所以 docment 并不能從之前的 segment 中移除或更新。
所以每次 commit, 生成 commit point 時(shí),會(huì)有一個(gè) .del 文件,里面會(huì)列出被刪除的 document(邏輯刪除)。
而查詢時(shí),獲取到的結(jié)果在返回前會(huì)經(jīng)過 .del 過濾。更新時(shí),也會(huì)標(biāo)記舊的 docment 被刪除,寫入到 .del 文件,同時(shí)會(huì)寫入一個(gè)新的文件。
此時(shí)查詢會(huì)查詢到兩個(gè)版本的數(shù)據(jù),但在返回前會(huì)被移除掉一個(gè)。
segment 合并
每 1s 執(zhí)行一次 refresh 都會(huì)將內(nèi)存中的數(shù)據(jù)創(chuàng)建一個(gè) segment。
segment 數(shù)目太多會(huì)帶來(lái)較大的麻煩。每一個(gè) segment 都會(huì)消耗文件句柄、內(nèi)存和 cpu 運(yùn)行周期。
更重要的是,每個(gè)搜索請(qǐng)求都必須輪流檢查每個(gè) segment ;所以 segment 越多,搜索也就越慢。
在 ES 后臺(tái)會(huì)有一個(gè)線程進(jìn)行 segment 合并:
refresh 操作會(huì)創(chuàng)建新的 segment 并打開以供搜索使用。
合并進(jìn)程選擇一小部分大小相似的 segment,并且在后臺(tái)將它們合并到更大的 segment 中。這并不會(huì)中斷索引和搜索。
當(dāng)合并結(jié)束,老的 segment 被刪。
說明合并完成時(shí)的活動(dòng):
新的 segment 被刷新(flush)到了磁盤。 寫入一個(gè)包含新 segment 且排除舊的和較小的 segment的新 commit point。
新的 segment 被打開用來(lái)搜索。
老的 segment 被刪除。
物理刪除:在 segment merge 這塊,那些被邏輯刪除的 document 才會(huì)被真正的物理刪除。
到此,相信大家對(duì)“Elasticsearch的原理是什么”有了更深的了解,不妨來(lái)實(shí)際操作一番吧!這里是創(chuàng)新互聯(lián)網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!