ZooKeeper選Leader算法、Zookeeper選舉算法( FastLeader選主)

轉載自:https://www.jianshu.com/p/07114f1ee595

概念

  • logicalclock: ZooKeeper服務器Leader選舉的輪次

  • electionEpoch: 當前服務器的選舉輪次,每次進入新一輪投票後進行加1操作

  • peerEpoch: 被推薦的Leader的選舉輪次

  • 外部投票: 特指其他服務器發來的投票

  • 內部投票: 服務器自身當前的投票

  • Zookeeper規定了所有有效的投票都必須在同一輪次

ZXID設計

一個ZXID是64位,高32是紀元(epoch)編號,每經過一次leader選舉產生一個新的leader,新leader會將epoch號+1。低32位是消息計數器,每接收到一條消息這個值+1,新leader選舉後這個值重置爲0,可以簡單理解epoch爲皇帝的年後,低位32位爲朝中的大臣,真所謂一朝天子、一朝臣。

選舉流程

ZooKeeper選主的接口是Election,默認的具體實現類是FastLeaderElection,接下來主要走讀下lookForLeader()方法。代碼參考zookeeper-3.4.5

  1. 當前服務器選舉輪次加1操作

  2. 更新提案,默認將票投給你自己

  3. 將提案通知給其他服務器,通知的時候會將logicalclock賦值給electionEpoch,即完成加1操作

沒有外部投票的處理流程

有外部投票的處理流程

  1. 外部投票的輪次大於內部投票
    更新服務器的投票輪次,然後內部投票和外部投票PK,具體PK或得提案,具體PK算法見下圖。

  2. 中外部投票輪次小於內部投票
    直接忽略

  3. 中外部投票輪次等於內部投票
    內部投票和外部投票PK,具體PK算法見下圖

PK算法

  1. 外部投票中被推薦Leader服務器的選舉輪次大於內部投票,提案變更。

  2. 輪次相同,外部投票被推薦Leader服務器的ZXID大於內部投票,提案變更。

  3. ZXID相同,外部投票被推薦Leader服務器的SID大於內部投票,提案變更。(SID是serverId)

過半投票認可當前內部投票

  1. 過半投票認可當前內部投票

  2. 有沒有被推薦的Leader

  3. 更新服務器狀態(leading,observing,following)

總流程

參考:從Paxos到Zookeeper分佈式一致性原理與實踐

區分外部投票輪次,外部投票中被推薦Leader投票輪次,內部同理


        /*
         * Epoch 投票輪次
         */
        long electionEpoch;

        /*
         * epoch of the proposed leader 被推薦Leader投票輪次
         */
        long peerEpoch;

簡單總結選主流程(模擬選舉一個NB的人)

  1. 在沒有遇到比我牛的人之前,第一票推薦我自己。

  2. 我有一個票箱,保存了當前這一輪選舉中自己的推薦人以及接收到的推薦人信息,一人一票,重複或過期的票概不接受,當我發現了比我推薦的牛人還牛的時候,改爲推薦這個牛人,否則,我還是推薦我自己。如果我發現我的選舉輪數落後了,清空票箱,改爲推薦接收到的最新選舉中大家推薦的最牛的那個人(如果沒有人比我牛,那還是推薦我自己)。

  3. 不斷的重複上面的過程,不斷的告訴別人“我的投票是第幾輪”、“我推舉的人是誰”。直到我的票箱中“我推舉的最牛的人”收到了不少於N/2+1的推舉投票,此時這個人就是我認定的最終leader。

  4. 當我確定了誰是最終 leader 並且這個 leader 一切正常,我就更新我的狀態爲 FOLLOWING/LEADING(我自己是最終 leader 則是 LEADING 否則就是 FOLLOWING),之後的選舉中都直接反饋我確定的這個最終 leader。

問題

提交已被Leader Commit的事務

發生場景

Leader發送Propose請求,Follower F1和Follower F2都向Leader回覆了ACK,Leader向所有的Follower發送Commit請求並Commit自身,此時Leader宕機,Leader已經Commit,但Follower尚未Commit,數據不一致。

處理方式

選舉F.zxid最大的Follower成爲新的準Leader,由於舊Leader宕機前,半數或以上的Follower曾經發送ACK消息,新的準Leader必然是這半數或以上Follower的一員;新的準Leader會發現自身存在已經Propose但尚未Commit的事務Proposal,新的準Leader會向所有的Follower先發送Propose請求,再發送Commit請求。

丟棄只被Leader Propose的事務

發生場景

Leader收到了事務請求,將其包裝成了事務Proposal,此時Leader宕機,Follower並沒有收到Propose請求,Follower進入選舉階段,選舉產生新Leader,舊的Leader重啓,以Follower的角色加入集羣,此時舊Leader上有一個多餘的事務Proposal,數據不一致。

處理方式

新的準Leader會根據自己服務器上最後被提交的事務Proposal和Follower的事務Proposal進行對比,然後新的準Leader要求Follower執行一個回退操作,回退到一個已經被集羣半數以上機器提交的最新的事務Proposal。



==============================

 

 

 

 

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