mon選舉流程總結

選舉的觸發條件

mon 的選舉會在3中情況下觸發:

1.     mon啓動,bootstrap階段。

2.     收到其它mon發送的選舉請求,Elector::handle_propose時,如果自身滿足一定條件會發起選舉。

3.     ceph命令觸發quorum變動時。

 

選舉的關鍵環節

bootstrap階段的選舉大致可以分爲兩個階段:準備階段和選舉階段。

準備階段

在選舉前要準備monmap和quorum或outside_quorum(主要是outside_quorum的準備,quorum是在一次成功的選舉之後才通過acked_me賦值的,不是從配置文件中讀取的,非bootstrap第一次選舉的情形用quorum.).這些是通過向monmap中和extra_probe_peers中的mon發送OP_PROBE消息,其它mon回覆的OP_REPLY消息中獲取的。extra_probe_peers是指給mon發送個OP_PROBE消息且fsid相同但不在monmap中的mon.

選舉階段

當monmap,quorum等必要條件滿足以後,則會發起選舉,可能多個mon同時發起選舉。當集羣第一次啓動時,是通過outside_quorum中的選舉成員完成選舉的,此時quorum爲空。如果想要發起選舉,mon必須滿足以下條件:

1、 自己必須處於STATE_PROBING或STATE_ELECTING狀態。

2、 其它mon通過OP_REPLY消息自身沒有參加過任何選舉 或 mon參加過選舉且自己的election_epoch比其它mon返回的epoch高。

3、 paxos版本足夠高,不必從其它mon同步數據。

4、 quorum或outside_quorum中成員的數量達到monmap中成員數量的一半以上。

 

由於接收消息的時間差等,滿足要求的mon可能不止一個,多個mon會同時發起請求,從這方面說mon的選主並不是一次典型的basic paxos過程。多個mon同時發起選主請求時,決定最終能否獲勝的關鍵因素是rank值的大小,rank值最小的才能獲得最終的勝利。

多個mon發起選主,向quorum(ouside_quorum)中的成員發送OP_PROPOSE消息,是否否會收到回覆呢?不是。只有滿足下面兩個條件纔會收到其它mon的回覆:

1、 epoch要比其它mon的epoch大。

2、 接受方沒有回覆過其它mon或自己的rank值小於接收到回覆過的mon的rank值。

 

前面多次提到過epoch,那麼epoch是如何生成的呢?epoch有兩種方式生成,一是啓動時從leveldb中讀取,然後+1變爲奇數,奇數代表選舉階段,偶數時穩態,如果leveldb中沒有,賦值爲1。二是準備階段根據其它mon返回的消息中epoch的值設置。

 

上面的限制能否覆蓋一下異常情況呢。我們來考慮以下兩種情況,看能不能保證rank值最小的mon在最終的選舉勝出。

有mon0,mon1,mon2,對應的rank值分別爲0,1,2.

情形1:由於消息傳遞時間的原因,mon1已經在選舉中勝出,mon0再發送選舉請求,mon0還能勝出嗎?能。因爲此時mon1,mon2收到消息後都會進行處理,如果滿足mon0的epoch版本更高且mon0的rank值更小,就會回覆消息。Elector.cc中void Elector::handle_propose()處理。

情形2:系統中新加入了一個mon,且這個mon的rank值最小,以mon0爲例,由於mon0是新安裝的,所以epoch版本肯定小於當前集羣中穩態的epoch的值,那麼mon0還能在選舉中獲勝嗎?能。mon1,mon2在收到消息後會重新調用start_election,mon0在收到mon1或mon2發來的消息後,由於自己的epoch<m-epoch,會調用bump_epoch來更新自己的版本信息,然後mon0重新調用start_elction發起選舉,也是在void Elector::handle_propose()處理的。

rank值來自於哪裏呢?從monmap中獲取,monmap也是有版本號的,會用其它mon的高版本的monmap更新自己的monmap.

 

選主基本代碼流程分析參考:

http://blog.csdn.net/scaleqiao/article/details/52315468

 

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