Elasticsearch 參考指南(讀和寫文檔)

讀和寫文檔

本節簡要介紹Elasticsearch的數據複製模型。html

介紹

Elasticsearch中的每一個索引都分爲碎片,每一個碎片能夠有多個副本,這些副本稱爲複製組,在添加或刪除文檔時必須保持同步。若是咱們不這樣作,從一個副本中讀取將致使與從另外一個副本讀取的結果大相徑庭,保持碎片副本同步並從中提供讀取的過程就是咱們所說的數據複製模型。git

Elasticsearch的數據複製模型基於主備模型,並在微軟研究院的PacificA paper論文中獲得了很好的描述。該模型基於從複製組中持有一個副本做爲主碎片,其餘副本稱爲副本碎片。主碎片服務做爲全部索引操做的主要入口點,它負責驗證它們並確保它們是正確的,一旦主碎片接受了索引操做,主碎片負責將操做複製到其餘副本。github

本節的目的是對Elasticsearch複製模型做一個高層次的概述,並討論它對讀和寫操做之間的各類交互的影響。segmentfault

基礎寫模型

Elasticsearch中的每一個索引操做首先使用路由解析爲一個複製組,一般基於文檔ID,一旦肯定了複製組,操做將在內部轉發到當前組的主碎片,主碎片負責驗證操做並將其轉發到其餘副本。因爲副本能夠脫機,主碎片不須要複製到全部副本,相反,Elasticsearch維護一個應該收到操做的碎片副本列表,這個列表稱爲同步副本,由主節點維護。顧名思義,這些是一組「好的」碎片副本,它們保證已經處理了已向用戶確認的全部索引和刪除操做,主碎片負責維護這個不變量,所以必須將全部操做複製到這個集合中的每一個副本。網絡

主碎片遵循這個基本流程:併發

  1. 驗證傳入的操做並在結構上無效時拒絕它(例如:有一個對象字段,其中一個數字是預期的)。
  2. 在本地執行操做,即索引或刪除相關文檔,這還將驗證字段的內容並在必要時拒絕(例如:在Lucene中用於索引的一個關鍵字太長)。
  3. 將操做轉發到當前同步副本集合中的每一個副本,若是有多個副本,則並行執行。
  4. 一旦全部副本都成功地執行了操做並響應了主碎片,主碎片就會對客戶端確認請求已經成功完成。

故障處理

在索引過程當中,許多事情均可能出錯 - 磁盤可能會損壞、節點之間可能斷開鏈接、或某些配置錯誤可能致使副本上的操做失敗,儘管它在主碎片上是成功的,這種狀況並不常見,但主碎片必須對其做出響應。elasticsearch

在主碎片失敗的狀況下,主碎片所在的節點將向主節點發送關於主碎片失敗的消息,索引操做將等待(默認狀況下最多1分鐘),以便主節點將一個副本提高爲一個新的主碎片。而後,操做將被轉發到新的主碎片進行處理,注意,主節點還監控節點的健康情況,並可能決定主動降級主碎片,這一般發生在持有主碎片的節點因爲網絡問題與集羣隔離時。ide

在主碎片上成功執行操做以後,當在副本碎片上執行操做時,主碎片必須處理潛在的故障,這多是因爲副本上的實際故障,或者是因爲網絡問題阻止操做到達副本(或者阻止副本響應)。全部這些都有相同的最終結果:同步副本集合中的一個副本錯過一個將要被確認的操做,爲了不違反不變量,主碎片向主節點發送一條消息,請求從同步副本集合中刪除有問題的碎片。只有在主節點確認移除碎片後,主碎片纔會確認操做,注意,主節點還將指示另外一個節點開始構建一個新的碎片副本,以便將系統恢復到健康狀態。網站

在將操做轉發到副本時,主碎片將使用副原本驗證它仍然是活動的主碎片,若是主碎片因爲網絡分區(或長時間GC)而被隔離,在乎識到主碎片已經被降級以前它可能會繼續處理傳入的索引操做,來自過時的主碎片的操做將被副本拒絕。當主碎片收到來自副本的拒絕它請求的響應,由於它再也不是主碎片時,它會聯繫主節點,並將會知道它已經被替換了,而後將操做路由到新的主碎片。ui

若是沒有副本會發生什麼?

這是一個因爲索引配置或僅僅由於全部副本都失敗而可能發生的有效場景,在這種狀況下,主碎片是在沒有任何外部驗證的狀況下處理操做,這可能看起來有問題,另外一方面,主碎片自己不能使其餘碎片失敗,但請求主節點表明它這樣作,這意味着主節點知道主碎片是惟一一個好的副本。所以,咱們保證主節點不會將任何其餘(過時的)碎片副本提高爲新的主碎片,而且主碎片中索引的任何操做都不會丟失,固然,由於此時咱們只運行數據的一個副本,因此物理硬件問題可能致使數據丟失。

基礎讀模型

在Elasticsearch中的讀能夠是很是輕量的經過ID的查找,也能夠是使用複雜聚合的繁重搜索請求,而複雜的聚合會佔用大量的CPU資源。主備模型的優勢之一是保持全部碎片副本相同(除了飛行的操做以外),所以,一個同步副本就足以服務於讀請求。

當節點接收到讀請求時,該節點負責將其轉發到持有相關碎片的節點、整理響應並響應客戶端,咱們將該節點稱爲該請求的協調節點,基本流程以下:

  1. 將讀請求解析到相關的碎片,注意,因爲大多數搜索將被髮送到一個或多個索引,它們一般須要從多個碎片中讀,每一個碎片表明數據的不一樣子集。
  2. 從碎片複製組中選擇每一個相關碎片的活動副本,這能夠是主碎片,也能夠是副本,默認狀況下,Elasticsearch將會在碎片副本之間進行簡單的循環負載。
  3. 將碎片級別的讀請求發送到選中的副本。
  4. 組合結果和響應,注意,在get by ID查找的狀況下,只有一個碎片是相關的,能夠跳過這一步。

故障處理

當碎片沒法響應讀請求時,協調節點將從同一複製組中選擇另外一個副本,並將碎片級搜索請求發送到該副本,重複的失敗會致使碎片副本不可用。在某些狀況下,好比_search,Elasticsearch將更喜歡快速響應,儘管會獲得部分結果,而不是等待問題獲得解決(響應的_shards頭中顯示了部分結果)。

幾個簡單的含義

這些基礎流中的每個都決定了Elasticsearch做爲讀寫系統的行爲,此外,因爲讀寫請求能夠併發執行,這兩個基本流相互交互,這有一些內在的含義:

高效的讀

  • 在正常操做下,對每一個相關複製組執行一次讀操做,只有在失敗的狀況下,同一個碎片的多個副本纔會執行相同的搜索。

未確認的讀

  • 因爲主碎片首先本地索引,而後複製請求,因此併發讀可能在確認更改以前就已經看到了更改。

默認爲兩個副本

  • 這個模型能夠在當只維護數據的兩個副本時容錯,這與基於數量的系統造成對比,其容錯的最小副本數爲3。

故障

在故障的狀況下,如下是可能的狀況:

單個碎片能夠減慢索引速度

  • 由於主碎片在每次操做期間都要等待同步複製集中的全部副本,因此單個慢碎片可能會減慢整個複製組的速度,這是咱們爲上述讀效率所付出的代價,固然,單個慢碎片也會不幸的減慢被路由到它的搜索。

髒讀

孤立的主碎片能夠公開不被認可的寫操做,這是由這樣一個事實引發的:一個孤立的主碎片只有在向其副本發送請求或與主節點接觸時纔會意識到它是孤立的,這時,操做已經被索引到主碎片中,而且能夠被併發讀取,Elasticsearch經過每秒ping一次主節點(默認狀況下)並在若是不知道主節點的狀況下拒絕索引操做來減輕這種風險。

冰山一角

本文檔提供了Elasticsearch如何處理數據的高層次概述,固然,在引擎下還有不少事情要作,像主碎片項、集羣狀態發佈和主節點選舉等都在保持系統正常運行方面發揮了做用,本文檔也沒有已知的和重要的bug(關閉和打開),咱們認識到Github很難跟上,爲了幫助人們保持在這些之上,咱們在咱們的網站上維護一個專用的彈性頁面,咱們強烈建議你閱讀它。


下一篇:Index API

相關文章
相關標籤/搜索