一、zookeeper叢集
配置多個執行個體共同構成一個叢集對外提供服務以達到水準擴充的目的,每個伺服器上的資料是相同的,每一個伺服器均可以對外提供讀和寫的服務,這點和redis是相同的,即對用戶端來講每個伺服器都是平等的。
這篇主要分析leader的選擇機制,zookeeper提供了三種方式:
- LeaderElection
- AuthFastLeaderElection
- FastLeaderElection (最新預設)
預設的算法是FastLeaderElection,是以這篇主要分析它的選舉機制。
二、選舉流程簡述
目前有5台伺服器,每台伺服器均沒有資料,它們的編号分别是1,2,3,4,5,按編号依次啟動,它們的選擇舉過程如下:
- 伺服器1啟動,給自己投票,然後發投票資訊,由于其它機器還沒有啟動是以它收不到回報資訊,伺服器1的狀态一直屬于Looking(選舉狀态)。
- 伺服器2啟動,給自己投票,同時與之前啟動的伺服器1交換結果,由于伺服器2的編号大是以伺服器2勝出,但此時投票數沒有大于半數,是以兩個伺服器的狀态依然是LOOKING。
- 伺服器3啟動,給自己投票,同時與之前啟動的伺服器1,2交換資訊,由于伺服器3的編号最大是以伺服器3勝出,此時投票數正好大于半數,是以伺服器3成為上司者,伺服器1,2成為小弟。
- 伺服器4啟動,給自己投票,同時與之前啟動的伺服器1,2,3交換資訊,盡管伺服器4的編号大,但之前伺服器3已經勝出,是以伺服器4隻能成為小弟。
- 伺服器5啟動,後面的邏輯同伺服器4成為小弟。
三、選擇機制中的概念
1、Serverid:伺服器ID
比如有三台伺服器,編号分别是1,2,3。
編号越大在選擇算法中的權重越大。
2、Zxid:資料ID
伺服器中存放的最大資料ID.
值越大說明資料越新,在選舉算法中資料越新權重越大。
3、Epoch:邏輯時鐘
或者叫投票的次數,同一輪投票過程中的邏輯時鐘值是相同的。每投完一次票這個資料就會增加,然後與接收到的其它伺服器傳回的投票資訊中的數值相比,根據不同的值做出不同的判斷。
4、Server狀态:選舉狀态
- LOOKING,競選狀态。
- FOLLOWING,随從狀态,同步leader狀态,參與投票。
- OBSERVING,觀察狀态,同步leader狀态,不參與投票。
- LEADING,上司者狀态。
四、選舉消息内容
在投票完成後,需要将投票資訊發送給叢集中的所有伺服器,它包含如下内容。
- 伺服器ID
- 資料ID
- 邏輯時鐘
- 選舉狀态
五、選舉流程圖
因為每個伺服器都是獨立的,在啟動時均從初始狀态開始參與選舉,下面是簡易流程圖。
六、選舉狀态圖
描述Leader選擇過程中的狀态變化,這是假設全部執行個體中均沒有資料,假設伺服器啟動順序分别為:A,B,C。
七、判斷是否已經勝出
預設是采用投票數大于半數則勝出的邏輯。
八、選舉流程詳述
一、首先開始選舉階段,每個Server讀取自身的zxid。
二、發送投票資訊
a、首先,每個Server第一輪都會投票給自己。
b、投票資訊包含 :所選舉leader的Serverid,Zxid,Epoch。Epoch會随着選舉輪數的增加而遞增。
三、接收投票資訊
1、如果伺服器B接收到伺服器A的資料(伺服器A處于選舉狀态(LOOKING 狀态)
1)首先,判斷邏輯時鐘值:
a)如果發送過來的邏輯時鐘Epoch大于目前的邏輯時鐘。首先,更新本邏輯時鐘Epoch,同時清空本輪邏輯時鐘收集到的來自其他server的選舉資料。然後,判斷是否需要更新目前自己的選舉leader Serverid。判斷規則rules judging:儲存的zxid最大值和leader Serverid來進行判斷的。先看資料zxid,資料zxid大者勝出;其次再判斷leader Serverid,leader Serverid大者勝出;然後再将自身最新的選舉結果(也就是上面提到的三種資料(leader Serverid,Zxid,Epoch)廣播給其他server)
b)如果發送過來的邏輯時鐘Epoch小于目前的邏輯時鐘。說明對方server在一個相對較早的Epoch中,這裡隻需要将本機的三種資料(leader Serverid,Zxid,Epoch)發送過去就行。
c)如果發送過來的邏輯時鐘Epoch等于目前的邏輯時鐘。再根據上述判斷規則rules judging來選舉leader ,然後再将自身最新的選舉結果(也就是上面提到的三種資料(leader Serverid,Zxid,Epoch)廣播給其他server)。
2)其次,判斷伺服器是不是已經收集到了所有伺服器的選舉狀态:若是,根據選舉結果設定自己的角色(FOLLOWING還是LEADER),退出選舉過程就是了。
最後,若沒有收到沒有收集到所有伺服器的選舉狀态:也可以判斷一下根據以上過程之後最新的選舉leader是不是得到了超過半數以上伺服器的支援,如果是,那麼嘗試在200ms内接收一下資料,如果沒有新的資料到來,說明大家都已經預設了這個結果,同樣也設定角色退出選舉過程。
2、 如果所接收伺服器A處在其它狀态(FOLLOWING或者LEADING)。
a)邏輯時鐘Epoch等于目前的邏輯時鐘,将該資料儲存到recvset。此時Server已經處于LEADING狀态,說明此時這個server已經投票選出結果。若此時這個接收伺服器宣稱自己是leader, 那麼将判斷是不是有半數以上的伺服器選舉它,如果是則設定選舉狀态退出選舉過程。
b) 否則這是一條與目前邏輯時鐘不符合的消息,那麼說明在另一個選舉過程中已經有了選舉結果,于是将該選舉結果加入到outofelection集合中,再根據outofelection來判斷是否可以結束選舉,如果可以也是儲存邏輯時鐘,設定選舉狀态,退出選舉過程。