每個 sever 首先給自己投票,然後用自己的選票和其他 sever 選票對比,權重大的勝出,使用權重較大的更新自身選票箱。具體選舉過程如下:
1. 每個 Server 啓動以後都詢問其它的 Server 它要投票給誰。對於其他 server 的詢問,server 每次根據自己的狀態都回復自己推薦的 leader 的 id 和上一次處理事務的 zxid(系統啓動時每個 server 都會推薦自己)。
2. 收到所有 Server 回覆以後,就計算出 zxid 最大的那個 Server,並將這個 Server 相關信息設置成下一次要投票的 Server。
3. 計算這過程中獲得票數最多的的 sever 爲獲勝者,如果獲勝者的票數超過半數,則該server 被選爲 leader。否則,繼續這個過程,直到 leader 被選舉出來。
4. leader 就會開始等待 server 連接。
5. Follower 連接 leader,將最大的 zxid 發送給 leader。
6. Leader 根據 follower 的 zxid 確定同步點,至此選舉階段完成。
7. 選舉階段完成 Leader 同步後通知 follower 已經成爲 uptodate 狀態。
8. Follower 收到 uptodate 消息後,又可以重新接受 client 的請求進行服務了。
目前有 5 臺服務器,每臺服務器均沒有數據,它們的編號分別是 1,2,3,4,5,按編號依次啓動,它們的選擇舉過程如下:
1. 服務器 1 啓動,給自己投票,然後發投票信息,由於其它機器還沒有啓動所以它收不到反饋信息,服務器 1 的狀態一直屬於 Looking。
2. 服務器 2 啓動,給自己投票,同時與之前啓動的服務器 1 交換結果,由於服務器 2 的編號大所以服務器 2 勝出,但此時投票數沒有大於半數,所以兩個服務器的狀態依然是LOOKING。
3. 服務器 3 啓動,給自己投票,同時與之前啓動的服務器 1,2 交換信息,由於服務器 3 的編號最大所以服務器 3 勝出,此時投票數正好大於半數,所以服務器 3 成爲領導者,服務器1,2 成爲小弟。
4. 服務器 4 啓動,給自己投票,同時與之前啓動的服務器 1,2,3 交換信息,儘管服務器 4 的編號大,但之前服務器 3 已經勝出,所以服務器 4 只能成爲小弟。
5. 服務器 5 啓動,後面的邏輯同服務器 4 成爲小弟。
3、Zookeeper 工作原理(原子廣播)
1. Zookeeper 的核心是原子廣播,這個機制保證了各個 server 之間的同步。實現這個機制的協議叫做 Zab 協議。Zab 協議有兩種模式,它們分別是恢復模式和廣播模式。
2. 當服務啓動或者在領導者崩潰後,Zab 就進入了恢復模式,當領導者被選舉出來,且大多數 server 的完成了和 leader 的狀態同步以後,恢復模式就結束了。
3. 狀態同步保證了 leader 和 server 具有相同的系統狀態
4. 一旦 leader 已經和多數的 follower 進行了狀態同步後,他就可以開始廣播消息了,即進入廣播狀態。這時候當一個 server 加入 zookeeper 服務中,它會在恢復模式下啓動,發現 leader,並和 leader 進行狀態同步。待到同步結束,它也參與消息廣播。Zookeeper服務一直維持在 Broadcast 狀態,直到 leader 崩潰了或者 leader 失去了大部分的followers 支持。
5. 廣播模式需要保證 proposal 被按順序處理,因此 zk 採用了遞增的事務 id 號(zxid)來保證。所有的提議(proposal)都在被提出的時候加上了 zxid。
6. 實現中 zxid 是一個 64 爲的數字,它高 32 位是 epoch 用來標識 leader 關係是否改變,每次一個 leader 被選出來,它都會有一個新的 epoch。低 32 位是個遞增計數。
7. 當 leader 崩潰或者 leader 失去大多數的 follower,這時候 zk 進入恢復模式,恢復模式需要重新選舉出一個新的 leader,讓所有的 server 都恢復到一個正確的狀態。