3.4 Elasticsearch的數據一致性
3.4.1 PacificA算法
Elasticsearch的數據存儲模型基於的是主從模式,其具體實現中借鑒了微軟的PacificA算法的一些思想理念。這里我們先簡單介紹一下PacificA算法
1)特點
- 設計了一個通用和抽象的復制框架,模型容易驗證正確性,實現不同的策略實例
- 配置管理和數據復制分離,Paxos負責管理配置,主副本策略負責數據復制
- 將錯誤檢測和配置更新容在數據復制的交互里面,去中心化,降低瓶頸
2)專業術語
- Replica Group:互為副本的一組數據的集合,其中有一個primary,其余都是secondary
- Configuration: Repica Group的元數據,如副本有哪些,誰是primary等
- Configuration Manager: 配置一致性管理工具
- Serial Number(SN): 代表Update的執行順序,每次update增加1
- Prepared List: Update操作的序列
- Committed List: 已經提交的update序列,是Prepared List的前綴
3)讀寫流程
寫入流程
- 寫請求進入主副本節點(簡稱主節點),該節點為它分配一個SN。使用SN創建一個
updateRequest
,然后將其插入prepareList
- 主節點將
updateRequest
發送給從副本節點(簡稱從副本)。從節點在接收到只有同樣將其插入到自身的prepare list
之中,然后返回一個ack
給主節點 - 當主節點接收到所有從節點的ack之后,認為這條數據已經被所有從節點正確接收,此時可以進行提交,將此
UpdateRequest
放入committed list
,committed list
向前移動。 - 主節點告知客戶端成功操作。對於每一個Prepare消息,主節點告知所有從節點自己
committed point
的位置。從節點在收到通知后移動自身committed point
到相同位置。
因為主節點只有在收到所有從節點ack之后才會提交數據到
committed list
,這樣就保證了所有從節點中的數據始終是主節點數據的子集,從而保證了數據的一致性
讀取流程
為了能夠獲取到最新的數據,所有讀取操作只能在主節點中進行。如果應用可以容忍一定的讀取窗口,也可以在從節點中進行
4)配置管理
全局的配置管理器負責管理所有副本組的設置。節點可以向管理器提出變更副本的請求,但必須附帶上當前配置的版本號。只有當版本號與配置器版本號一致時,配置器才會響應變更請求
5)故障檢測
pacificA通過租約機制來(lease)來進行主節點和從節點間的互相檢測。主節點會定期向從節點獲取租約,其可能產生以下情況
- 從節點沒有及時(lease period)回復。主節點向配置管理器報告從節點異常,同時將自身降級
- 主節點沒有及時(grace period)回復。從節點向配置管理器報告主節點異常,同時提升自己為新的主節點。當有多個從節點同時發現主節點異常時,按照先來后到的順序提升
通過簡單分析可知,當grace period > lease period時,就不會出現二主的問題
當發生網絡分區時,由於grace period > lease period,那么主必然先探測到從下線,於是自身降級。而從探測到主下線之后提升自己為主。由於這時主已經下線,所以不存在二主的情況
6)ES中的PacificA
- master類似於配置管理器,負責維護索引信息
- SequenceNumber和Checkpoint類似PacificA算法中的Serial Number和Committed Point
- 集群狀態中的routing_table存儲了所有索引、索引有哪些shard、各自的主分片,以及位於哪個節點等信息,類似副本組
3.4.2 Elasticsearch中的分片如何工作
ES會把索引拆分成多個主分片來進行存儲,同時,這些主分片都有多個副本。這些副本就是replication group(副本組)。這種數據副本模型屬於主備模式,主分片是所有索引操作的入口。它負責檢查操作是否有效,一旦主分片接收操作,其副本也要接收相應的操作
1)寫入
概述
每個索引操作首先會解析到相應的副本組中,然后內部路由到相應的主分片上,主分片負責驗證操作並轉發請求到副本上。
ES在運行時,master會維護一個同步副本列表(in-sync copies),該列表包含了所有可用的副本和主分片信息,其中的副本都可以保證完成所有的索引處理操作,並給用戶返回ack。主分片負責維護數據的一致性,因此必須將操作同步給在列表中的全部副本
流程圖

異常處理
-
主分片寫入失敗
- 主分片節點通知master給自己降級,重新選一個主分片
-
副本寫入失敗
- 主分片通知master,將該副本從同步副本列表中移除,同時master會在其余節點重建該副本
-
主分片網絡隔離
- 副本會拒絕來自過時主分片的操作。主分片訪問master來獲取最新的狀態
-
沒有任何副本
- 可以成功寫入,但是數據安全無法保證。也可以設置
wait_for_active_shards
來保證數據安全性
- 可以成功寫入,但是數據安全無法保證。也可以設置
2)讀取
概述
主從模式下的一個好處就是所有主分片和副本的數據都是一致的(正在同步的除外)。因此主分片和同步副本列表中的副本均可以提供讀取服務,這么做可以極大的提供吞吐量,提供優秀的並發性能。所以讀取操作可以在同步副本列表(in-sync copies)中的任意分片上進行
流程圖

注意
- 對於部分請求(如_search),ES傾向於及時返回結果,即使這個結果不是完整的
- 在正常情況下,讀操作只在相關分片中執行一次,除非當讀取有錯誤發生
- 對於在寫操作響應前的讀操作,有一定可能獲取到還未寫成功的數據。(因為寫操作需要全部分片確認,而只要有一個分片寫完,那么就有可能讀取到這個數據)