elasticsearch文檔讀寫模型

前面兩篇文章,向讀者介紹了Elasticsearch中REST API的基本規範,相信讀者閱讀完後,對REST API已經有了一個基本的認識,從本篇文章開始,要慢慢向讀者介紹文檔的相關操作了,那麼在詳細介紹文檔的相關操作之前,本文先來對文檔相關讀寫操作做一個簡單概述。

本文是Elasticsearch系列的第七篇,閱讀前面的文章,有助於更好的理解本文


1.模型簡介

Elasticsearch中的每個索引都會進行分片,每個分片又都會有多個副本,這些副本稱爲replication group,在添加或刪除文檔時這些副本也必須保持同步,否則在數據讀取時就會出現數據紊亂,保持分片副本的同步並從中提供讀取的過程就是我們所說的data replication model。

Elasticsearch的數據複製模型基於 主-備模型,在這個模型下,分片分爲主分片和副本分片,主分片是所有索引操作的主要入口點,它負責驗證並確保所有操作是正確的,一旦主分片接受了索引操作,主分片在索引操作執行成功後還要負責將操作複製到其他副本。

2.寫模型

Elasticsearch中的每個索引操作首先通過路由解析到replication group,這一操作通常基於文檔ID,一旦replication group被確定後,索引操作將在內部轉發到replication group的當前主分片上,主分片將負責驗證操作並將操作轉發到其他副本。由於副本可以離線,因此不需要將主分片複製到所有副本,Elasticsearch會維護一個應該接收操作的分片副本列表,這個列表稱爲同步副本並由主節點維護。顧名思義,這些是“好”分片副本的集合。

主分片遵循以下基本流程:

  1. 驗證輸入操作並在結構無效時拒絕它(例如:想要一個數字結果給了一個對象)
  2. 先在本地執行操作,例如索引或刪除相關文檔,如果執行出錯時也將拒絕(例如:關鍵字值太長,無法在Lucene中進行索引)
  3. 將操作轉發到當前同步副本集中的每個副本。如果有多個副本,則並行執行該操作
  4. 一旦所有副本成功執行了操作並響應給主服務器,主服務器就會確認成功完成對客戶端的請求

2.1 故障處理

在索引的過程可能會出現各種各樣的異常情況,例如:1.磁盤損壞;2.節點相互斷開連接;3.由於配置錯誤導致複製副本上的操作失敗,儘管它在主服務器上操作成功,等等。雖然這些問題並不一定常見,但是開發者還是有必要作出相應的預案。 在主分片本身發生故障的情況下,託管主分片的節點將向Master發送有關它的消息,此時索引操作將等待(默認情況下最多1分鐘),以便Master將其中一個副本提升爲新主分片,然後,該操作將被轉發到新的主分片處理。 請注意,Master還會監控節點的運行狀況,並可能決定主動對主分片進行降級(這通常是由於網絡問題導致的)。一旦在主分片上成功執行了操作,主分片就必須處理在副本上執行操作時存在的潛在故障,這些潛在的故障可能是由副本上的實際故障或由於網絡問題導致操作無法到達副本(或阻止副本響應)引起的。所有這些都具有相同的最終結果:同步副本集中的一部分副本錯過了即將被確認的操作。此時,主分片向Master發送消息,請求從同步副本集中刪除有問題的分片。只有在Master確認刪除了分片後,主分片纔會確認操作。注意,Master還將指示另一個節點開始構建新的分片副本,以便將系統還原到正常狀態。 在將操作轉發到副本時,主分片將使用副本來驗證它仍然是活動主分片。如果主分片由於網絡原因(或長GC)而被分離,它依然可能會在被降級之前繼續處理傳入的索引操作,此時副本將拒絕來自舊主分片的操作。主分片收到副本的拒絕請求後會請求Master節點,Master會告訴舊的主分片你已經被替換掉,然後操作會被路由到新的主分片。

2.2 如果沒有副本會怎麼樣

由於索引的配置原因或者所有副本都已失效,在這種情況下,會發生主分片沒有副本。此時,主分片處理操作而沒有任何外部驗證,這可能看起來有問題。另一方面,主分片本身不能使其他分片失效,但可以請求Master代表它執行此操作。這意味着Master知道主分片是唯一的好副本。因此,我們保證Master不會將任何其他(過時的)分片副本提升爲新的主分片,並且任何索引到主分片的操作都不會丟失。當然,由於此時我們只使用單個數據副本運行,因此物理硬件問題可能導致數據丟失。

3.讀模型

Elasticsearch中的讀取操作,可以是按照ID查找這種非常輕量級的操作,也可以是具有複雜聚合的大量搜索請求,這些聚合操作會佔用非常大的CPU算力。 主-備模型的優點之一是它使所有分片副本保持一致(除了飛行中的操作)。基於此,單個同步的副本足以處理讀取請求。 當節點收到讀取請求時,該節點負責將其轉發到保存相關分片的節點,整理響應並對客戶端做出響應。此時,我們將該節點稱爲該請求的協調節點,該節點的基本工作流程如下:

  1. 對讀取請求進行解析,然後將請求分發到不同分片上。請注意,由於大多數搜索請求將被髮送到一個或多個索引,因此它們通常需要從多個分片中讀取,每個分片代表數據的不同子集。
  2. 從replication group中選擇每個相關分片的可用副本,可以是主分片或副本。默認情況下,Elasticsearch將簡單地在分片副本之間循環。
  3. 將分片級讀取請求發送到所選副本。
  4. 整合請求結果並給客戶端作出響應,注意,在通過ID查找的情況下,只有一個分片是相關的,並且可以跳過此步驟(即不需要整合請求結果,用過MyCat的讀者,可能會發現這個步驟的作用和MyCat比較類似)。

3.1 故障處理

當分片無法響應讀取請求時,協調節點將從同一複製組中選擇另一個副本,並將分片級別搜索請求發送到該副本,不過要是重複失敗可能導致沒有可用的分片副本。在某些情況下,例如search請求中,Elasticsearch更願意快速響應,而不是等待問題得到解決(此時雖然只有部分結果,部分結果會在shards中指出)。

4.一些簡單的含義

這些基本流程確定了Elasticsearch讀取和寫入系統的行爲。此外,由於讀取和寫入請求可以同時執行,因此這兩個基本流程彼此交互,有一些固有的含義:

4.1 Efficient reads

在正常操作下,對每個相關的replication group執行一次讀取操作。只有在失敗的情況下,纔會對同一個分片的多個副本執行相同的搜索。

4.2 Read unacknowledged

由於主分片首先在本地進行索引,然後將操作發給副本去執行,因此併發讀取可能在確認之前就已經看到了更改的數據。

4.3 Two copies by default

此模型可以容錯,同時只保留兩個數據副本。這與基於法定數量的系統形成對比(容錯的最小副本數爲3)。

5.關於操作失敗

在操作失敗的情況下,以下是可能的:

1.單個分片可以減慢索引速度

由於主分片在每個操作期間等待同步副本集中的所有副本,因此單個分片操作速度慢可能會降低整個replication group的速度。這是我們爲上述閱讀效率付出的代價,同時,單個慢速分片也會降低已經路由到它的搜索請求。

2.髒讀

被隔離的主分片可以執行寫操作,但是卻無法被確認,這是因爲隔離的主分片只有在向其副本發送請求或向Master發送請求時纔會意識到它是隔離的。此時,操作已經索引到主分片中,並且可以通過併發讀取來讀取。Elasticsearch通過每秒ping一次Master(默認情況下)並在沒有Master的情況下拒絕索引操作來減輕這種風險。

好了,本文先介紹到這裏,有問題歡迎留言討論。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章