點擊關注"愛笑的架構師"程序員
右上角"設爲星標"好文章不錯過web
Zookeeper
是一個分佈式服務框架,主要是用來解決分佈式應用中遇到的一些數據管理問題如:統一命名服務
、狀態同步服務
、集羣管理
、分佈式應用配置項的管理
等。面試
咱們能夠簡單把 Zookeeper
理解爲分佈式家庭的大管家,那麼管家團隊是如何選出Leader
的呢?好奇嗎,接下來帶領你們一探究竟。算法
人類選舉的基本原理
講解 Zookeeper
選舉過程前先來介紹一下人類的選舉。服務器
咱們每一個人或多或少都經歷過幾回選舉,在投票的過程當中可能會遇到這樣幾種狀況:微信
狀況1:本身與幾個候選人都比較熟,你會將票投給你認爲能力比較強的人
;架構
狀況2:本身也是候選人,而且與其餘幾個候選人都不熟,這個時候你確定想着要去拉票,由於以爲本身才是最厲害的人呀,全部人都應該把票投給我。可是遺憾的是在拉票的過程當中,你發現別人比你強
,你開始自卑了,最終仍是把票投給了本身認爲最強的人。app
全部人都投完票以後,最後從投票箱中進行統計,得到票數最多的人當選。框架
在整個投票過程當中咱們能夠提煉出四個最核心的概念:編輯器
-
候選人能力
:投票的基本原則是選最強的人。 -
遇強改投
:若是後面發現更強的人能夠改投票。 -
投票箱
:全部人的票都會放在投票箱。 -
領導者
:得票最多的人即爲領導者。
從人類選舉的原理咱們來簡單推導一下Zookeeper的選舉原理。
Zookeeper選舉的基本原理
注意若是 Zookeeper 是單機部署是不須要選舉的,集羣模式下才須要選舉。
Zookeeper 的選舉原理和人類選舉的邏輯相似,套用一下人類選舉的四個基本概念詳細解釋一下Zookeeper。
-
我的能力
如何衡量 Zookeeper 節點我的能力?答案是靠數據是否夠新
,若是節點的數據越新就表明這個節點的我的能力越強,是否是感受很奇怪,就是這麼定的!
在 Zookeeper 中一般是以事務id(後面簡稱zxid
)來標識數據的新舊程度(版本),節點最新的zxid越大表明這個節點的數據越新,也就表明這個節點能力越強。
zxid 的全稱是
ZooKeeper Transaction Id
,即 Zookeeper 事務id。
-
遇強改投
在集羣選舉開始時,節點首先認爲本身是最強的(即數據是最新的),而後在選票上寫上本身的名字(包括zxid
和sid
),zxid 是事務id,sid 惟一標識本身。
緊接着會將選票傳遞給其餘節點,同時本身也會接收其餘節點傳過來的選票。每一個節點接收到選票後會作比較,這我的是否是比我強(zxid比我大),若是比較強,那我就須要改票
,明明別人比我強,我也不能厚着臉皮對吧。
-
投票箱
與人類選舉投票箱稍微有點不同,Zookeeper 集羣會在每一個節點的內存中維護一個投票箱。節點會將本身的選票以及其餘節點的選票都放在這個投票箱中。因爲選票是互相傳閱的,因此最終每一個節點投票箱中的選票會是同樣的。
-
領導者
在投票的過程當中會去統計是否有超過一半的選票和本身選擇的是同一個節點,即都認爲某個節點是最強的。一旦集羣中有超過半數
的節點都認爲某個節點最強,那該節點就是領導者了,投票也宣告結束。
什麼場景下 Zookeeper 須要選舉?
當 Zookeeper 集羣中的一臺服務器出現如下兩種狀況之一時,須要進入 Leader 選舉
。
(1)服務器初始化啓動。
(2)服務器運行期間 Leader 故障。
啓動時期的 Leader 選舉
假設一個 Zookeeper 集羣中有5臺服務器,id從1到5編號,而且它們都是最新啓動的,沒有歷史數據。
假設服務器依次啓動,咱們來分析一下選舉過程:
(1)服務器1啓動
發起一次選舉,服務器1投本身一票,此時服務器1票數一票,不夠半數以上(3票),選舉沒法完成。
投票結果:服務器1爲1票。
服務器1狀態保持爲LOOKING
。
(2)服務器2啓動
發起一次選舉,服務器1和2分別投本身一票,此時服務器1發現服務器2的id比本身大,更改選票投給服務器2。
投票結果:服務器1爲0票,服務器2爲2票。
服務器1,2狀態保持LOOKING
(3)服務器3啓動
發起一次選舉,服務器一、二、3先投本身一票,而後由於服務器3的id最大,二者更改選票投給爲服務器3;
投票結果:服務器1爲0票,服務器2爲0票,服務器3爲3票。此時服務器3的票數已經超過半數(3票),服務器3當選Leader
。
服務器1,2更改狀態爲FOLLOWING
,服務器3更改狀態爲LEADING
。
(4)服務器4啓動
發起一次選舉,此時服務器1,2,3已經不是LOOKING 狀態,不會更改選票信息。交換選票信息結果:服務器3爲3票,服務器4爲1票。此時服務器4服從多數,更改選票信息爲服務器3。
服務器4並更改狀態爲FOLLOWING
。
(5)服務器5啓動
與服務器4同樣投票給3,此時服務器3一共5票,服務器5爲0票。
服務器5並更改狀態爲FOLLOWING
。
最終的結果:
服務器3是 Leader
,狀態爲 LEADING
;其他服務器是 Follower
,狀態爲 FOLLOWING
。
運行時期的Leader選舉
在 Zookeeper運行期間 Leader
和 非 Leader
各司其職,當有非 Leader 服務器宕機或加入不會影響 Leader,可是一旦 Leader 服務器掛了,那麼整個 Zookeeper 集羣將暫停對外服務,會觸發新一輪的選舉。
初始狀態下服務器3當選爲Leader
,假設如今服務器3故障宕機了,此時每一個服務器上zxid可能都不同,server1爲99,server2爲102,server4爲100,server5爲101
運行期選舉與初始狀態投票過程基本相似,大體能夠分爲如下幾個步驟:
(1)狀態變動。Leader 故障後,餘下的非 Observer
服務器都會將本身的服務器狀態變動爲LOOKING
,而後開始進入Leader選舉過程
。
(2)每一個Server會發出投票。
(3)接收來自各個服務器的投票,若是其餘服務器的數據比本身的新會改投票。
(4)處理和統計投票,每一輪投票結束後都會統計投票,超過半數便可當選。
(5)改變服務器的狀態,宣佈當選。
話很少說先來一張圖:
(1)第一次投票,每臺機器都會將票投給本身。
(2)接着每臺機器都會將本身的投票發給其餘機器,若是發現其餘機器的zxid比本身大,那麼就須要改投票從新投一次。好比server1 收到了三張票,發現server2的xzid爲102,pk一下發現本身輸了,後面果斷改投票選server2爲老大。
選舉機制中涉及到的核心概念
敲黑板了,這些概念是面試必考的。
(1)Server id(或sid):服務器ID
好比有三臺服務器,編號分別是1,2,3。編號越大在選擇算法中的權重越大,好比初始化啓動時就是根據服務器ID進行比較。
(2)Zxid:事務ID
服務器中存放的數據的事務ID,值越大說明數據越新,在選舉算法中數據越新權重越大。
(3)Epoch:邏輯時鐘
也叫投票的次數,同一輪投票過程當中的邏輯時鐘值是相同的,每投完一次票這個數據就會增長。
(4)Server狀態:選舉狀態
LOOKING
,競選狀態。
FOLLOWING
,隨從狀態,同步leader狀態,參與投票。
OBSERVING
,觀察狀態,同步leader狀態,不參與投票。
LEADING
,領導者狀態。
總結
(1)Zookeeper 選舉會發生在服務器初始狀態和運行狀態下。
(2)初始狀態下會根據服務器sid的編號對比,編號越大權值越大,投票過半數便可選出Leader。
(3)Leader 故障會觸發新一輪選舉,zxid
表明數據越新,權值也就越大。
(4)在運行期選舉還可能會遇到腦裂的狀況,你們能夠自行學習。
- END -
閒聊:最近雷架常常回復讀者的疑問,有時候一不當心就寫了800字,這麼有責任感的雷架大家肯定不勾搭一下?😄 微信搜索 smileCoder1024 添加我的微信,須要加羣能夠備註」加羣「。
好文推薦(點擊可閱讀):
做者簡介:
你們好,我是"愛笑的架構師"公號做者,你能夠叫我"雷架"。
讀過幾年書:華中科技大學碩士畢業;
浪過幾個大廠:華爲、網易、百度……
一直堅信技術能改變世界,願保持初心,加油技術人!
據說點個「在看」就有好運氣~
沒有什麼比天天有成長進步更高興的事情
本文分享自微信公衆號 - 愛笑的架構師(DancingOnYourCode)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。