Elasticsearch 架構原理

爲何要學習架構?

Elasticsearch的一些架構設計,對咱們作性能調優、故障處理,具備很是重要的影響。下面將從Elasticsearch的準實時索引的實現、自動發現、rounting和replica的讀寫過程,shard的allocate控制數據庫

使文本能夠被搜索?

在傳統的數據庫中,一個字段存一個值,可是這對於全文搜索是不足的。想要讓文本中的而每一個單詞均可以被搜索,這意味着數據庫須要多個值。apache

支持一個字段多個值的最佳數據結構是倒排索引。倒排索引包含了出如今全部文檔中惟一的值或或詞的有序列表,以及每一個詞所屬的文檔列表。緩存

倒排索引存儲了比包含一個term的文檔列表多地多的信息,它可能包含每個term的文檔數量,一個term出如今制定文檔中的頻次,每一個文檔中term的順序,每一個文檔的長度,全部文檔的平均長度等等。這些統計信息讓Elasticsearch知道哪些term更重要,哪些文檔更重要,也就是相關性。數據結構

在全文搜索的早些時候,會爲整個文檔集合創建一個大索引,而且寫入磁盤。只有新索引準備好了它就會替代舊的索引,最近的修改能夠被檢索。架構

不可變性性能

寫入磁盤的倒排索引是不可變的,它有以下好處:學習

  • 不須要鎖。若是歷來不須要跟新一個索引,就沒必要擔憂多個程序見同時嘗試修改。
  • 一旦索引被讀入文件系統的緩存,它就一直在那兒,由於不會改變。只要文件系統緩存有足夠的空間,大部分的讀會直接訪問內存而不是磁盤。這有助於性能的提高。
  • 在索引的聲明週期內,全部的其餘緩存均可用。他們不須要再每次數據變化了都重建,所以數據不會變。
  • 寫入單個大的倒排索引,能夠壓縮數據,較少的磁盤IO和須要緩存索引的大小。

準實時索引的實現?

本文主要介紹Elasticsearch的準實時索引的實現,至於基於Lucene的倒排索引將不在這裏介紹,有興趣的讀者能夠去Lucene的相關文章,或者閱讀《Lucene in Action》等書籍。下面將介紹Elasticsearch索引流程中發生的具體操做,重點在於其中的segment、buffer和translog三部分對性能方面的影響。spa

一、動態更新的Lucnee索引

要作到實時跟新條件下數據的可用和可靠,就須要在倒排索引的基礎上,再作一系列更高級的處理。總結一下Lucene的處理辦法:新收到的數據寫入新的索引文件裏。Lucene把每次生成的倒排索引,叫作一個段(segment)。而後另外使用一個commit文件,記錄索引內的全部segment。而生成segment的數據來源,則是內存中的buffer,也就是說,動態跟新事後過程以下:1)當前磁盤上有三個segement可用,同時有一個commit文件記錄當前的segment2)新收到的數據進入內存buffer,索引狀態以下所示。3)buffer刷到磁盤,生成一個新的segment,commit文件同步跟新。這樣能夠完成跟新,也產生了幾個問題:一、每次一有數據就刷新到磁盤,會增大對磁盤的操做架構設計

二、刷新到磁盤的時間佔據很大一部分時間三、若是刷新的過程當中刷新失敗應該怎麼控制呢?設計

二、刪除和更新

segment是不可變的,因此文檔即不能從舊的段中刪除,舊的段也不能更新以反映文檔最新的文本。相反,每個提交點包括一個.del文件,包含了段上已經被刪除的文檔當一個文檔被刪除,它是實際上只是在.del文件中被標記刪除,亦然能夠匹配查詢,但最終返回以前會被從結果中刪除。文檔的更新操做是相似的:當一個文檔被更新,舊版本的文檔被標記爲刪除,新版本的文檔在新的段中索引。也許該文檔的不一樣版本都會匹配一個查詢,可是老版本會從結果中刪除。

三、利用磁盤緩存實現的準實時檢索

既然涉及到磁盤,那麼一個不可避免的問題就來了:磁盤太慢了!對咱們要求的實時性很高的服務來講,這種處理還不夠。因此,在剛剛第3步的處理中,還有一箇中間狀態:1)內存buffer生成一個新的segment,刷到文件系統緩存中,Lucene便可檢索到這個新的segment,索引狀態如圖所示。2)文件系統緩存真正同步到磁盤上,commit文件跟新。刷到文件系統緩存中這個步驟,Elasticsearch默認1s的時間間隔,這也就是說至關因而實時搜索的,Elasticsearch也提供了單獨的/_reflush接口,用戶若是對1s間隔仍是不太滿意,能夠主動調用接口來保證搜索可見。

POST /_refresh <1>
POST /blogs/_refresh <2>
  • <1> refresh全部索引
  • <2> 只refresh 索引blogs

通常來講咱們會經過/_settings接口或者定製template的方式,加大refresh_interval參數:

PUT /my_logs/_settings{ "refresh_interval": -1 } <1>
PUT /my_logs/_settings{ "refresh_interval": "1s" } <2>
  • <1> 禁用全部自動refresh
  • <2> 每秒自動refresh

四、translog提供的磁盤同步控制

既然refresh只是寫到文件系統緩存中,那麼最後一步寫到實際磁盤又是由什麼來控制的呢?若是這期間發生主機錯誤、硬盤故障等異常狀況,數據會不會丟失?這裏,其實Elasticsearch提供了另外一個機制來控制。Elasticsearch也把數據寫入到內存buffer的同時,其實還另外記錄了一個treanslog的日誌。也就是說,在內存數據進入到buffer這一步驟時,其實還另外記錄了一個translog記錄。

相關文章
相關標籤/搜索