Elasticsearch是如何選舉出master的
Elasticsearch的任意一個節點都可以設置node.master和node.data屬性,該屬性的意義如下表所示
master \ data
|
true | false |
---|---|---|
true | 既是Master Eligible,又是data節點 | 單純的Master Eligible節點 |
false | 單純的data節點 | 純粹的Coordinating Node,協調節點負責查詢時的數據收集、合並以及聚合等操作,ES中所有節點都是協調節點 |
在來自於流行病的Gossip協議一文中我們已經知道了Elasticsearch中所有的節點是如何組成為一個集群的,接下來我們了解ES集群中是如何選出master的。
選舉的基本原則
ES針對當前集群中所有的Master Eligible Node進行選舉得到master節點,為了避免出現Split-brain現象,ES選擇了分布式系統常見的quorum(多數派)思想,也就是只有獲得了超過半數選票的節點才能成為master。在ES中使用 discovery.zen.minimum_master_nodes
屬性設置quorum,這個屬性一般設置為 eligibleNodesNum / 2 + 1
。
如何觸發一次選舉
當滿足如下條件是,集群內就會發生一次master選舉
- 當前master eligible節點不是master
- 當前master eligible節點與其它的節點通信無法發現master
- 集群中無法連接到master的master eligible節點數量已達到
discovery.zen.minimum_master_nodes
所設定的值
如何選舉
當某個節點決定要進行一次選舉是,它會實現如下操作
- 尋找clusterStateVersion比自己高的master eligible的節點,向其發送選票
- 如果clusterStatrVersion一樣,則計算自己能找到的master eligible節點(包括自己)中節點id最小的一個節點,向該節點發送選舉投票
- 如果一個節點收到足夠多的投票(即
minimum_master_nodes
的設置),並且它也向自己投票了,那么該節點成為master開始發布集群狀態
下面我們用一個實際的例子來解釋選舉流程,假設有node_a和node_b,node_a向node_b發送選票。
- 如果node_b已經是master,則node_b就把node_a加入集群,之后node_b發布最新的集群狀態,此時node_a會被包含在最新的集群狀態里面。
- 如果node_b正在進行選舉,則node_b會把這次投票記錄下來,之后node_b可能成為master或者繼續等待選票。node_a等待node_b發送最新的集群狀態或者超時觸發下一次投票。
- 如果node_b認為自己不會成為master,則拒絕這次投票,node_a將觸發下一次投票。
其它的選舉辦法
Zookeeper
事實上ES可以使用Zookeeper來進行master選舉,方法如下
- 所有master eligible嘗試在zk上創建指定路徑
- 只有第一個節點能創建成功,該節點成為master,其余節點watch此路徑
- 一旦zk失去master的連接,該路徑被刪除,其余master eligible繼續嘗試創建路徑,同樣只能有一個節點成功創建並成為master
- 重復以上步驟
Zookeeper來實現選主可以使得ES內部的選舉算法變得非常的簡單,至於為什么ES要自己發明一套輪子就不是很清楚了。
Raft
ES本身的選舉算法在早期還是比較粗糙的,這些年來也在不斷改進中。Raft算法本身經過嚴格的論證,是一種非常優秀的一致性算法,至於ES沒有選擇使用Raft而是自己發明了一套選舉算法的原因則很簡單,因為ES早期版本的時候Raft算法還沒有被提出來,不過我認為隨着ES的發展應該會更多的參考這些已經經過嚴格論證的選舉算法。
Raft作為一種分布式一致性協議,其本身不止描述了選舉過程,還提供了日志同步與安全性的相關行為的描述。
參考
ElasticSearch 內部機制淺析(一)
Master Election
Leader Election, Why Should I Care?
Elasticsearch分布式一致性原理剖析(一)-節點篇 √
ELASTICSEARCH 選主流程