Elasticsearch Lucene 數據寫入原理 | ES 核心篇

前言html

最近 TL 分享了下 《Elasticsearch基礎整理》,蹭着這個機會。寫個小文鞏固下,本文主要講 ES -> Lucene
的底層結構,而後詳細描述新數據寫入 ES 和 Lucene 的流程和原理。這是基礎理論知識,整理了一下,但願能對 Elasticsearch 感興趣的同窗有所幫助。apache

1、Elasticsearch & Lucene 是什麼

圖片描述

什麼是 Elasticsearch ?
Elasticsearch 是一個基於 Apache Lucene(TM) 的開源搜索引擎。segmentfault

那 Lucene 是什麼?
不管在開源仍是專有領域,Lucene 能夠被認爲是迄今爲止最早進、性能最好的、功能最全的搜索引擎庫,並經過簡單的 RESTful API 來隱藏 Lucene 的複雜性,從而讓全文搜索變得簡單。緩存

Elasticsearch 不只僅是 Lucene 和全文搜索,咱們還能這樣去描述它:服務器

  • 分佈式的實時文件存儲,每一個字段都被索引並可被搜索
  • 分佈式的實時分析搜索引擎
  • 能夠擴展到上百臺服務器,處理 PB 級結構化或非結構化數據

2、Elasticsearch & Lucene 的關係

圖片描述

就像不少業務系統是基於 Spring 實現同樣,Elasticsearch 和 Lucene 的關係很簡單:Elasticsearch 是基於 Lucene 實現的。ES 基於底層這些包,而後進行了擴展,提供了更多的更豐富的查詢語句,而且經過 RESTful API 能夠更方便地與底層交互。相似 ES 還有 Solr 也是基於 Lucene 實現的。socket

在應用開發中,用 Elasticsearch 會很簡單。可是若是你直接用 Lucene,會有大量的集成工做。elasticsearch

所以,入門 ES 的同窗,稍微瞭解下 Lucene 便可。若是往高級走,仍是須要學習 Lucene 底層的原理。由於倒排索引、打分機制、全文檢索原理、分詞原理等等,這些都是不會過期的技術。分佈式

3、新文檔寫入流程

3.1 數據模型

圖片描述

如圖ide

  • 一個 ES Index (索引,好比商品搜索索引、訂單搜索索引)集羣下,有多個 Node (節點)組成。每一個節點就是 ES 的實例。
  • 每一個節點上會有多個 shard (分片), P1 P2 是主分片 R1 R2 是副本分片
  • 每一個分片上對應着就是一個 Lucene Index(底層索引文件)
  • Lucene Index 是一個統稱。由多個 Segment (段文件,就是倒排索引)組成。每一個段文件存儲着就是 Doc 文檔。

3.2 Lucene Index

圖片描述

lucene 中,單個倒排索引文件稱爲 segment。其中有一個文件,記錄了全部 segments 的信息,稱爲 commit point:性能

  • 文檔 create 新寫入時,會生成新的 segment。一樣會記錄到 commit point 裏面
  • 文檔查詢,會查詢全部的 segments
  • 當一個段存在文檔被刪除,會維護該信息在 .liv 文件裏面

3.3 新文檔寫入流程

新文檔建立或者更新時,進行以下流程:

更新不會修改原來的 segment,更新和建立操做都會生成新的一個 segment。數據哪裏來呢?先會存在內存的 bugger 中,而後持久化到 segment 。

數據持久化步驟以下:write -> refresh -> flush -> merge

3.3.1 write 過程

圖片描述

一個新文檔過來,會存儲在 in-memory buffer 內存緩存區中,順便會記錄 Translog。

這時候數據還沒到 segment ,是搜不到這個新文檔的。數據只有被 refresh 後,才能夠被搜索到。那麼 講下 refresh 過程

3.3.2 refresh 過程

圖片描述

refresh 默認 1 秒鐘,執行一次上圖流程。ES 是支持修改這個值的,經過 index.refresh_interval 設置 refresh (沖刷)間隔時間。refresh 流程大體以下:

  • in-memory buffer 中的文檔寫入到新的 segment 中,但 segment 是存儲在文件系統的緩存中。此時文檔能夠被搜索到
  • 最後清空 in-memory buffer。注意: Translog 沒有被清空,爲了將 segment 數據寫到磁盤

文檔通過 refresh 後, segment 暫時寫到文件系統緩存,這樣避免了性能 IO 操做,又可使文檔搜索到。refresh 默認 1 秒執行一次,性能損耗太大。通常建議稍微延長這個 refresh 時間間隔,好比 5 s。所以,ES 其實就是準實時,達不到真正的實時。

3.3.3 flush 過程

圖片描述

上個過程當中 segment 在文件系統緩存中,會有意外故障文檔丟失。那麼,爲了保證文檔不會丟失,須要將文檔寫入磁盤。那麼文檔從文件緩存寫入磁盤的過程就是 flush。寫入次怕後,清空 translog。

translog 做用很大:

  • 保證文件緩存中的文檔不丟失
  • 系統重啓時,從 translog 中恢復
  • 新的 segment 收錄到 commit point 中

具體能夠看官方文檔:https://www.elastic.co/guide/...

3.3.4 merge 過程

圖片描述

圖片描述

上面幾個步驟,可見 segment 會愈來愈多,那麼搜索會愈來愈慢?怎麼處理呢?

經過 merge 過程解決:

  • 就是各個小段文件,合併成一個大段文件。段合併過程
  • 段合併結束,舊的小段文件會被刪除
  • .liv 文件維護的刪除文檔,會經過這個過程進行清除

4、小結

圖片描述

如這個圖,ES 寫入原理不難,記住關鍵點便可。

write -> refresh -> flush

  • write:文檔數據到內存緩存,並存到 translog
  • refresh:內存緩存中的文檔數據,到文件緩存中的 segment 。此時能夠被搜到
  • flush 是緩存中的 segment 文檔數據寫入到磁盤

寫入的原理告訴咱們,考慮的點不少:性能、數據不丟失等等

(完)

參考資料:

原文連接:
sf:https://segmentfault.com/a/11...
csdn:https://bysocket.blog.csdn.ne......

相關文章
相關標籤/搜索