Elasticsearch是如何實現master選舉的?什麼是腦裂及如何避免腦裂

  1. Elasticsearch是如何實現master選舉的

master選舉默認是由zendiscovery模塊負責。
系統剛剛啓動的時候,選取id最小的備選master爲master節點。
系統運行起來之後,master和非master節點間是存在一個類似心跳檢測的ping機制的,當master ping不到其他節點,或者其他節點ping不到master的時候,他們之間就會互相判斷,是否大多數都連不到主節點上了,如果大多數都連不上,那麼就開始重新進行master選舉。
    master選舉的底層實現是對於所有的master備選節點的clustersate進行比較,選擇最新的clusterstate節點作爲主節點,如果有兩個節點的clusterstate值相同,那麼選擇id較小也就是較早的node作爲主節點。我猜測這樣選舉的原因是用最新clusterstate可以保證集羣處在最近的版本中,避免陳舊數據或操作的出現導致數據衝突,而用最早id其實也就是應用最先生成的節點的原因,應該是爲了保證集羣的穩定,最小的id應該最早執行完所有的數據一致性及各種操作了,所以可以保證數據的相對穩定。這樣選舉出來的一個主節點如果被大多數的備選主節點同意選爲主節點並且該節點也選擇自己作爲主節點,那麼這個節點就可當選,否則進行下一輪選舉,一直到選舉成功。
     這裏有兩個重要的配置,elasticsearch.yml文件中的
    discovery.zen.ping.unicast.hosts[]:這是一個master備選節點的主機表,所有想要加入集羣的節點都向他們發送請求來加入集羣。
    discovery.zen.mininum_master_nodes的數量最好設定爲備選主節點數量/2+1.因爲這個配置控制了選舉的最少節點數,即最少這麼多個節點投票通過才能選舉出master,否則不行,這樣,可以保證一個集羣中只有一個主節點。

  • 什麼是腦裂,Elasticsearch是如何避免腦裂現象的

腦裂現象就是一個集羣因爲網絡超時或其他原因產生了兩個或兩個以上以上的主節點的情況,可以理解爲一個大集羣分裂成了多個小集羣,這些小集羣各自有各自的master,各自爲政,能夠自己對數據進行操作,導致大集羣產生了數據不一致的現象。
爲了避免腦裂,es採取了一個大多數原則的解決方案:即選舉主節點時需要得到大多數的支持纔可成功選舉,需要配置文件中的discovery.zen.mininum_master_node的值爲所有master備選主節點的數量/2+1保證大多數的有參選資格的主節點都承認某一節點的master身份纔可以,這樣就保證了另一部分分裂出去的有參選資格的節點永遠也達不到n/2+1的數量,就保證了不會腦裂。
但是其實es的開發者還是忽略了一個問題,就是如果每一個有選舉資格的節點如果直投一票,那麼肯定可以避免腦裂,但是其實有些情況下,有選舉資格的節點時有機會透兩票的,比如有三備選個節點的集羣ABC,應該選a爲master,開始選舉 b先投了a,然後a也投了自己,符合大多數原則,按理應該a返回消息,告訴大家我當選,結束選舉,但是b投票後,網絡通訊變慢b遲遲沒收到a的回覆導致超時,b又投了c一票,此時c也與a斷開,也投了自己,c又當選,這時又出現了腦裂……相當於b投了兩票。但是其實這種情況es也做了處理,就是將將集羣狀態變更分爲兩個階段:提交和執行分開,不立即執行新操作。就是在當一個節點選爲master,需要先發佈一個clasterstate給各個節點,這個東西相當於一個版本號,告訴各個節點我當皇帝了 要按我的規矩來,節點收到之後,會先返回一個信息說收到了,但是不會立即執行,當大多數的節點都返回了成功接收的消息,節點纔會真正執行新的clasterstate更新。所以當上面這種情況出現腦裂,雖然在master分發新消息的時候可以被節點接收,但是commit的時候還是會發現不一致,不符合條件的master會自動放棄master狀態並重新加入集羣。
還有一種解決方案:就是可以將數據和主節點分離,還有當只有兩個節點時:設置其中一個爲主節點,nodedata爲false,另一個nodedata爲true,master爲false 

 

 

--所有原創內容,可以轉載,但請標明出處謝謝

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