Elasticsearch選舉原理之Bully算法

Elasticsearch採用了master-slave模式, ES會在集羣中選取一個節點成爲主節點,只有Master節點有資格維護全局的集羣狀態,在有節點加入或者退出集羣的時候,它會重新分配分片,並將集羣最新狀態發送給集羣中其它節點,主節點會以週期性ping的方式以驗證其它節點是否存活。Elasticsearch的選舉算法基於Bully選舉算法,簡單的說,在bully算法中,每個節點都有一個編號,只有編號最大的存活節點才能成爲master節點。

1. 選舉時間點

選舉的時間點有兩個

  1. 某個新節點加入了集羣或者某個節點從宕機中恢復
  2. 集羣中的某個節點檢測到leader崩潰

2. 選舉流程

選舉的流程說明如下

  1. 節點node向所有比自己大的節點發送選舉消息(選舉爲election消息)
  2. 如果節點node得不到任何回覆(回覆爲alive消息),那麼節點node成爲master,並向所有的其它節點宣佈自己是master(宣佈爲Victory消息)
  3. 如果node得到了任何回覆,node節點就一定不是master,同時等待Victory消息,如果等待Victory超時那麼重新發起選舉

筆者藉助網上的一組圖片詳細闡述Bully的選舉流程,圖片來自於

假設有如下6節點組成的集羣,每個節點都會維護和其它節點的聯繫,p6節點是當前集羣的master節點

在某個時間點master節點p6發生了宕機

 

P3節點是整個集羣中最先發現master節點宕機的節點,p3節點通知了比自己編號大的p4,p5節點,p6節點

 

因爲p6節點已經宕機,只有p4,p5節點向p3節點發出響應,並通知p3節點他們會取代p6節點成爲master節點

P4節點向P5,P6節點發送通知

因爲p6節點已經宕機,所以只有p5節點作出了響應

P5節點向P6節點發起選舉通知,P6節點沒有響應,於是P5節點成爲了整個集羣的master節點

P5節點成爲了整個集羣的master節點

3. Elasticsearch編號比較

Elasticsearch編號比較的判斷依據有兩個,首先是ClusterState版本號的比較,版本號越大優先級越高,然後是節點id的比較,id越小優先級越高。ClusterState是Master向集羣中各個節點發送的集羣狀態,這個狀態有一個版本號碼,如果集羣狀態發生了變化,比如集羣新增了節點成員或者有節點成員退出了,那麼這個版本號就會加一,比對這個版本號的目的是讓擁有最新狀態的節點成爲Master的優先級最高。

4. Bully算法缺陷

4.1 Master假死

Master節點承擔的職責負載過重的情況下,可能無法即時對組內成員作出響應,這種便是假死。如果上圖中的P6節點假死,於是P5節點成爲了Master節點,但是在P6節點負載減輕之後,P6節點又對組內成員作出了響應,P6節點又會成爲Master節點,如此反覆,整個集羣狀態就會非常不可靠。

Elasticsearch是如何解決這個問題的呢?在Bully算法中,Master節點P6因爲負載重,來不及對P3節點作出響應,所以P3節點通知P4,P5節點進行選舉。在Elasticsearch中,P3節點發現Master P6對自己長時間不作出響應,P3節點會請求其它節點判斷P6節點是否存活,如果有1/2以上節點都認定P6存活,那麼P3就會放棄發起選舉

4.2 腦裂問題

腦裂問題指的是一個集羣中出現了兩個及以上的Master節點。

比如上圖中集羣因爲網絡原因分成了兩個部分,一個部分稱爲partition1包含P3,P5,P6節點,另一部分稱爲partition2包含P2,P1,P4節點,這兩個partition因爲網絡原因比如路由器短時故障造成不能相互通信的問題。

 

那麼網絡分區一根據Bully算法選舉出了P6作爲master,而網絡分區二選舉出了P4作爲master,這就是腦裂問題。

Elasticsearch腦裂解決方案

Quorum算法

腦裂問題是所有集羣選舉算法都要面對的一個問題,Elasticsearch集羣機制採用了最小參與節點的方案解決的。假設elasticsearch集羣中有資格投票的實例個數是n,節點想要成爲master必須要得到n/2 +1票數(在本示例中是4)。上圖中的分區一P6和分區二中的P4,任何一個master節點所在的分區集羣的候選節點數目都小於4,更不可能得到4個選票,所以整個Elasticsearch集羣處於癱瘓狀態

我們也可以強制指定elasticsearch節點在有M個候選節點的情況下能選舉出一個主節點,但是如果配置數小於上文提到的 n/2 +1 那麼會出現腦裂的情況,M的配置參數如下

discovery.zen.minimum_master_nodes

如果產生了腦裂情況,爲了避免腦裂的Master生成錯誤數據對整個集羣產生影響。Master更新集羣狀態時還作出瞭如下防護,Master有兩種指令,一種是send指令,另一種是commit指令,Master將最新集羣狀態推送給其它節點的時候(這是send指令),Master節點進入等待響應狀態,其它節點並不會立刻應用該集羣狀態,而是首先會響應Master節點表示它已經收到集羣狀態更新,同時等待Master節點的commit指令。Master節點如果在discovery.zen.commit_timeout配置時間內都沒有收到discovery.zen.minimum_master_nodes個數的節點響應,那麼Master節點就不會向其它節點發送commit指令。如果Master收到了足夠數量的響應,那麼Master會向集羣發出提交狀態的指令,此時其它節點應用集羣最新狀態,Master節點再次等待所有節點響應,等待時間爲discovery.zen.publish_timeout,如果任何一個節點沒有發出提交響應,Master再次更新整個集羣狀態更新。

4.3 Master降級

Master主動降級發生在兩種情況。

第一種是master發現自己能連接到的其它節點數目小於n/2 + 1,那麼master自動降級爲candidate。

第二種是Master在ping其它節點時候,如果發現了其它master,那麼當前的master會比較cluster_state的version,如果當前master的version小,那麼主動降級爲candidate並主動加入另外一個master節點

4.4 網絡負載問題

從上圖中可以看到,集羣中每個節點成員都會維護和其它所有成員的交互,整個集羣維護的網絡連接的總數是n*(n-1),如果集羣中節點的數目非常的多,那麼網絡連接數目也會非常的多,網絡負載會比較大,但是好在elasticsearch節點數目往往比較少,所以這個缺陷對elasticsearch集羣來說不會產生什麼影響。在前一篇關於集羣發現的文章https://zhuanlan.zhihu.com/p/109570606中提到,elasticsearch可以通過參數限制單播的最大連接數目,該值默認爲10

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