螞蟻面試官:Zookeeper 的選舉流程是怎樣的?我當場懵逼了。。。
點擊關(guān)注公眾號,Java干貨及時送達
棧長面試經(jīng)常會遇到面試官問 Zookeeper 的選舉原理,我心想,問這些有啥用嗎?又不要我造火箭!
每次面試也只知道個大概,并沒有深究具體的流程,所以在面試的時候總是不能打動面試官,總是特別吃虧,所以這篇就總結(jié)一下其中的要點,也希望能幫助大家搞定面試。
有一說一, Zookeeper 這些工作原理、選舉流程,也許大多數(shù)人在工作中不會用到,但了解多一點也是自己的優(yōu)勢,避免求職面試被面試官打壓工資。Zookeeper 也是現(xiàn)在后端主流的分布式協(xié)調(diào)框架,很多熱門框架都有直接或者間接依賴它,比如:Dubbo、Elastic Job、Kafka 等,所以掌握 ZK 選舉流程也是非常有必要的。
本文會以通俗易懂的方式進行, ZK 小白也能看懂。另外,我也將 Zookeeper 系列主流面試題和參考答案都整理好了,關(guān)注公眾號Java技術(shù)棧回復關(guān)鍵字 "面試" 進行刷題。
基本概念
了解選舉前你得了解一些 Zookeeper 的基本概念。
集群機器 ID
集群機器 ID 是指 myid,它是每一個集群機器中的編號文件,代表 ZooKeeper 集群服務器的標識,手動生成,全局全一。
事務 ID
事務 ID 是指 zxid,Zookeeper 會給每個更新請求分配一個事務 ID,它是一個 64 位的數(shù)字,由 Leader 統(tǒng)一進行分配,全局唯一,不斷遞增,在一個節(jié)點的狀態(tài)信息中可以查看到最新的事務 ID 信息。
集群服務器角色
Zookeeper 集群服務器有以下 3 種角色:
1、Leader(主)
2、Follower(從,參與投票)
3、Observer(觀察者,不參與投票)
集群服務器狀態(tài)
Zookeeper 集群服務器有以下 4 種狀態(tài):
1、LOOKING
尋找 Leader 狀態(tài),當服務器處于該狀態(tài)時,表示當前集群沒有 Leader,因此會進入 Leader 選舉狀態(tài)。
2、FOLLOWING
跟隨者狀態(tài),表示當前服務器角色是 Follower。
3、LEADING
領(lǐng)導者狀態(tài),表示當前服務器角色是 Leader。
4、OBSERVING
觀察者狀態(tài),表示當前服務器角色是 Observer。
選舉方式
Zookeeper 提供了 3 種選舉方式:
LeaderElection AuthFastLeaderElection FastLeaderElection (最新默認)
選舉場景
Zookeeper 會在以下場景進行選舉:
1、Zookeeper 集群啟動初始化時進行選舉
2、Zookeeper 集群 Leader 失聯(lián)時重新選舉
選舉前提條件
1、Zookeeper 服務器處于 LOOKING 競選狀態(tài)
此時說明 Zookeeper 服務器集群處于群龍無首狀態(tài),另外,觀察者狀態(tài)不能參與競選投票。
2、Zookeeper 集群規(guī)模至少要 3 臺機器或以上
集群規(guī)則為:2N + 1臺,N > 0,即最少需要 3 臺,因為 ZK 集群的機制是只要超過半數(shù)的節(jié)點正常,集群就能正常提供服務。只有在 ZK 節(jié)點掛得太多,只剩一半或不到一半節(jié)點能工作時,集群才會失效。
如以下分析所示:
3 個節(jié)點的 Cluster 可以掛掉 1 個節(jié)點(Leader 可以得到 2 票 > 1.5)
2 個節(jié)點的 Cluster 就不能掛掉任何 1 個節(jié)點了(Leader 可以得到 1 票 <= 1)
所以你知道 ZK 集群為什么至少要 3 臺了吧?
3、Zookeeper 集群要 2 臺及以上機器可以互相通信
只要達到 2 臺服務器通信了才能進行選舉,只有一臺服務器啟動時無法進行選舉,因為服務器之間通信了才可以互相同步投票結(jié)果。
選舉流程
1、集群初始選舉
Zookeeper 在集群啟動時會進行選舉,這里拿 3 臺服務器進行舉例:
| server | myid | zxid |
|---|---|---|
| zk1 | 1 | 0 |
| zk2 | 2 | 0 |
| zk3 | 3 | 0 |
依次啟動 3 臺服務器 zk1, zk2, zk3,初始情況下事務 ID 都為 0。
選舉大致流程:
1、初始投票
服務器啟動后,每個 Server 都會給自己投上一票,每次投票會包含所投票服務器的 myid 和 zxid,這里使用 Server(myid, zxid)的方式表示,此時的投票結(jié)果為:zk1(1, 0),zk2(2, 0),zk3(3, 0)
2、同步投票結(jié)果
集群中的服務器在投票后,會將各自的投票結(jié)果同步給集群中其他服務器。
3、檢查投票有效性
各服務器在收到投票后會檢查投票的有效性,如:是否本輪投票,是否來自 LOOKING 狀態(tài)的服務器的投票等。
4、處理投票
服務器之間會進行投票比對,規(guī)則如下:
優(yōu)先檢查 zxid,較大的服務器優(yōu)先作為 Leader 如果 zxid 相同,則 myid 較大的服務器作為 Leader
如:zk1 和 zk2 進行比對,此時 zk2 勝出,zk1 更新自己的投票為:zk1(2, 0)
5、統(tǒng)計投票結(jié)果
每輪投票比對之后都會統(tǒng)計投票結(jié)果,確認是否有超過半數(shù)的機器都得到相同的投票結(jié)果,如果是,則選出 Leader,否則繼續(xù)投票。
本輪選舉中,zk1 和 zk2 都得到了相同的投票結(jié)果(2, 0),2 指 zk2,并且超過了半數(shù)的機器(2 > 3 / 2),所以此時 zk2 就成為了本輪選舉的 Leader。
所以,即使 zk3 啟動了,因為集群已經(jīng)有了 Leader,所以選舉也結(jié)束了,zk3 不再參與選舉,后面進來的都是小弟。
6、更改服務器狀態(tài)
一旦選出 Leader,每個服務器就會各自更新自己的狀態(tài):
zk1?>>>?FOLLOWING
zk2?>>>?LEADING
Zk3?>>>?FOLLOWING
2、集群重新選舉
Zookeeper 集群運行期間無法和 Leader 保持正常連接時,即如果 Leader 掛了,或者 Leader 服務器故障都會進行新一輪的 Leader 選舉。
這里還是拿 3 臺服務器進行舉例:
| server | myid | zxid |
|---|---|---|
| zk1(Follower) | 1 | 0 |
| zk2(Leader) | 2 | 0 |
| zk3(Follower) | 3 | 0 |
如果作為初始選舉的 Leader zk2 掛了,集群就會暫停對外提供服務,從而進行新的 Leader 選舉。
選舉大致過程:
1、狀態(tài)變更
既然過去的老大 Leader 不可用了,那所有的 Follower 服務器就需要從 FOLLOWING 狀態(tài)變更為:LOOKING,開始新的一輪 Leader 選舉。
2、開始投票
投票邏輯和啟動初始時一致。
zk1, zk3 第一輪投票默認還是會先投給自己,zk2 掛了不能進行投票。
第一輪投票結(jié)果為:zk1(1, 66)、zk3(3, 28),zk1 和 zk3 各得一票,這里假設(shè) zk1 事務 ID 比 zk3 更大一點。
3、同步投票結(jié)果
同步投票邏輯和啟動初始時一致。
4、檢查投票有效性
檢查投票邏輯和啟動初始時一致。
5、處理投票
處理投票邏輯和啟動初始時一致。
此時 zk1 和 zk3 進行比對,根據(jù)規(guī)則,由于 zk1 的事務 ID 更大一點,所以 zk1 勝出,zk3 也更新自己的投票為:zk3(1, 28)
6、統(tǒng)計投票結(jié)果
統(tǒng)計投票邏輯和啟動初始時一致。
本輪選舉中,zk1 和 zk3 都得到了相同的投票結(jié)果 zk1,并且超過了半數(shù)的機器(2 > 3 / 2),所以此時 zk1 就成為了本輪選舉的 Leader。
7、更改服務器狀態(tài)
更改狀態(tài)邏輯和啟動初始時一致。
總結(jié)
所以,我們可以總結(jié)下,Zookeeper 集群按 myid 從小到大依次啟動初始化時,在超過半數(shù)機器的投票的情況下,誰的 myid 最大,誰就是 Leader,知道這個定律,不同的集群規(guī)模我們都可以推算出誰是 Leader。
集群初始化時:
1)集群有 3 臺機器,第 2 大的 myid 所在服務器就是 Leader;
2)集群有 4 臺機器,第 3 大的 myid 所在服務器就是 Leader;
3)集群有 5 臺機器,第 3 大的 myid 所在服務器就是 Leader;
3)集群有 6 臺機器,第 4 大的 myid 所在服務器就是 Leader;
.....
集群重新選舉時,根據(jù) myid 和 zxid 的大小共同決斷,zxid 更大的優(yōu)先成為 Leader。
總之,誰得到半數(shù)以上的服務器支持,誰就是老大,Zookeeper 選舉流程你看懂了嗎?這只是粗略版的選舉流程,實際選舉過程要更復雜,有興趣的可以深入研究下源碼。
好了,今天的分享就到這里了,后面棧長會分享更多好玩的 Java 技術(shù)和最新的技術(shù)資訊,關(guān)注公眾號Java技術(shù)棧第一時間推送,我也將主流 Zookeeper 面試題和參考答案都整理好了,在公眾號后臺回復關(guān)鍵字 "面試" 進行刷題。
最后,覺得我的文章對你用收獲的話,動動小手,給個在看、轉(zhuǎn)發(fā),原創(chuàng)不易,棧長需要你的鼓勵。
版權(quán)聲明: 本文系公眾號 "Java技術(shù)棧" 原創(chuàng),原創(chuàng)實屬不易,轉(zhuǎn)載、引用本文內(nèi)容請注明出處,抄襲者一律舉報+投訴,并保留追究其法律責任的權(quán)利。







關(guān)注Java技術(shù)??锤喔韶?/strong>


