前言html
最近 TL 分享了下 《Elasticsearch基礎整理》,蹭着這個機會。寫個小文鞏固下,本文主要講 ES -> Lucene
的底層結構,而後詳細描述新數據寫入 ES 和 Lucene 的流程和原理。這是基礎理論知識,整理了一下,但願能對 Elasticsearch 感興趣的同窗有所幫助。apache
什麼是 Elasticsearch ?
Elasticsearch 是一個基於 Apache Lucene(TM) 的開源搜索引擎。segmentfault
那 Lucene 是什麼?
不管在開源仍是專有領域,Lucene 能夠被認爲是迄今爲止最早進、性能最好的、功能最全的搜索引擎庫,並經過簡單的 RESTful API 來隱藏 Lucene 的複雜性,從而讓全文搜索變得簡單。緩存
Elasticsearch 不只僅是 Lucene 和全文搜索,咱們還能這樣去描述它:服務器
就像不少業務系統是基於 Spring 實現同樣,Elasticsearch 和 Lucene 的關係很簡單:Elasticsearch 是基於 Lucene 實現的。ES 基於底層這些包,而後進行了擴展,提供了更多的更豐富的查詢語句,而且經過 RESTful API 能夠更方便地與底層交互。相似 ES 還有 Solr 也是基於 Lucene 實現的。socket
在應用開發中,用 Elasticsearch 會很簡單。可是若是你直接用 Lucene,會有大量的集成工做。elasticsearch
所以,入門 ES 的同窗,稍微瞭解下 Lucene 便可。若是往高級走,仍是須要學習 Lucene 底層的原理。由於倒排索引、打分機制、全文檢索原理、分詞原理等等,這些都是不會過期的技術。分佈式
如圖ide
lucene 中,單個倒排索引文件稱爲 segment。其中有一個文件,記錄了全部 segments 的信息,稱爲 commit point:性能
新文檔建立或者更新時,進行以下流程:
更新不會修改原來的 segment,更新和建立操做都會生成新的一個 segment。數據哪裏來呢?先會存在內存的 bugger 中,而後持久化到 segment 。
數據持久化步驟以下:write -> refresh -> flush -> merge
一個新文檔過來,會存儲在 in-memory buffer 內存緩存區中,順便會記錄 Translog。
這時候數據還沒到 segment ,是搜不到這個新文檔的。數據只有被 refresh 後,才能夠被搜索到。那麼 講下 refresh 過程
refresh 默認 1 秒鐘,執行一次上圖流程。ES 是支持修改這個值的,經過 index.refresh_interval 設置 refresh (沖刷)間隔時間。refresh 流程大體以下:
文檔通過 refresh 後, segment 暫時寫到文件系統緩存,這樣避免了性能 IO 操做,又可使文檔搜索到。refresh 默認 1 秒執行一次,性能損耗太大。通常建議稍微延長這個 refresh 時間間隔,好比 5 s。所以,ES 其實就是準實時,達不到真正的實時。
上個過程當中 segment 在文件系統緩存中,會有意外故障文檔丟失。那麼,爲了保證文檔不會丟失,須要將文檔寫入磁盤。那麼文檔從文件緩存寫入磁盤的過程就是 flush。寫入次怕後,清空 translog。
translog 做用很大:
具體能夠看官方文檔:https://www.elastic.co/guide/...
上面幾個步驟,可見 segment 會愈來愈多,那麼搜索會愈來愈慢?怎麼處理呢?
經過 merge 過程解決:
如這個圖,ES 寫入原理不難,記住關鍵點便可。
write -> refresh -> flush
寫入的原理告訴咱們,考慮的點不少:性能、數據不丟失等等
(完)
參考資料:
原文連接:
sf:https://segmentfault.com/a/11...
csdn:https://bysocket.blog.csdn.ne......