Apache ZooKeeper -从初始化到对外提供服务的过程解析( 集群模式 )
文章目錄
- 流程圖
- Pre
- 什么是集群模式?
- ZooKeeper 集群模式的特點
- 底層實現(xiàn)原理
- 程序啟動
- QuorumPeer 類
- Leader 服務(wù)器啟動過程
- Follow 服務(wù)器啟動過程
- 小結(jié)
流程圖
Pre
Apache ZooKeeper -從初始化到對外提供服務(wù)的過程解析( 單機(jī)模式 )
我們知道了 ZooKeeper 在單機(jī)模式下從啟動運行到對外提供服務(wù)的整個過程。在日常工作中,無論是出于性能上的優(yōu)勢還是可靠性的考慮,單機(jī)模式都無法滿足要求。因此,ZooKeeper 也采用集群的方式運行。我們就來學(xué)習(xí)一下 ZooKeeper 集群模式下,啟動過程的底層實現(xiàn)。
什么是集群模式?
為了解決單機(jī)模式下性能的瓶頸問題,以及出于對系統(tǒng)可靠性的高要求,集群模式的系統(tǒng)架構(gòu)方式被業(yè)界普遍采用。
集群模式可以簡單理解為將單機(jī)系統(tǒng)復(fù)制成幾份,部署在不同主機(jī)或網(wǎng)絡(luò)節(jié)點上,最終構(gòu)成了一個由多臺計算機(jī)組成的系統(tǒng)“集群”。而組成集群中的每個服務(wù)器叫作集群中的網(wǎng)絡(luò)節(jié)點。
那問題來了 我們應(yīng)該如何使用集群?當(dāng)客戶端發(fā)送一個請求到集群服務(wù)器的時候,究竟是哪個機(jī)器為我們提供服務(wù)呢?
為了解決這個問題,先介紹一個概念名詞“調(diào)度者”。調(diào)度者的工作職責(zé)就是在集群收到客戶端請求后,根據(jù)當(dāng)前集群中機(jī)器的使用情況,決定將此次客戶端請求交給哪一臺服務(wù)器或網(wǎng)絡(luò)節(jié)點進(jìn)行處理,例如我們都很熟悉的負(fù)載均衡服務(wù)器就是一種調(diào)度者的實現(xiàn)方式。
ZooKeeper 集群模式的特點
通過上面的介紹,我們知道了集群是由網(wǎng)絡(luò)中不同機(jī)器組成的一個系統(tǒng),集群工作是通過集群中調(diào)度者服務(wù)器來協(xié)同工作的。
那么現(xiàn)在我們來看一下 ZooKeeper 中的集群模式,在 ZooKeeper 集群模式中,相比上面說到的集群架構(gòu)方式,在 ZooKeeper 集群中將服務(wù)器分成 Leader 、Follow 、Observer 三種角色服務(wù)器,在集群運行期間這三種服務(wù)器所負(fù)責(zé)的工作各不相同:
- Leader 角色服務(wù)器負(fù)責(zé)管理集群中其他的服務(wù)器,是集群中工作的分配和調(diào)度者。
- Follow 服務(wù)器的主要工作是選舉出 Leader 服務(wù)器,在發(fā)生 Leader 服務(wù)器選舉的時候,系統(tǒng)會從 Follow 服務(wù)器之間根據(jù)多數(shù)投票原則,選舉出一個 Follow 服務(wù)器作為新的 Leader 服務(wù)器。
- Observer 服務(wù)器則主要負(fù)責(zé)處理來自客戶端的獲取數(shù)據(jù)等請求,并不參與 Leader 服務(wù)器的選舉操作,也不會作為候選者被選舉為 Leader 服務(wù)器。
接下來我們看看在 ZooKeeper 中集群是如何架構(gòu)和實現(xiàn)的。
底層實現(xiàn)原理
到目前為止我們對 ZooKeeper 中集群相關(guān)的知識有了大體的了解,接下來我們就深入到 ZooKeeper 的底層,看看在服務(wù)端,集群模式是如何啟動到對外提供服務(wù)的。
在上一篇博文中已經(jīng)對 ZooKeeper 單機(jī)版服務(wù)的啟動過程做了詳細(xì)的介紹。而集群中的啟動過程和單機(jī)版的啟動過程有很多地方是一樣的。所以本次我們只對 ZooKeeper 集群中的特有實現(xiàn)方式做重點介紹。
程序啟動
首先,在 ZooKeeper 服務(wù)啟動后,系統(tǒng)會調(diào)用入口 QuorumPeerMain 類中的 main 函數(shù)。在 main 函數(shù)中的 initializeAndRun 方法中根據(jù) zoo.cfg 配置文件,判斷服務(wù)啟動方式是集群模式還是單機(jī)模式。
在函數(shù)中首先根據(jù) arg 參數(shù)和 config.isDistributed() 來判斷,如果配置參數(shù)中配置了相關(guān)的配置項,并且已經(jīng)指定了集群模式運行,那么在服務(wù)啟動的時候就會跳轉(zhuǎn)到 runFromConfig 函數(shù)完成之后的集群模式的初始化工作。
protected void initializeAndRun(String[] args){...if (args.length == 1 && config.isDistributed()) {runFromConfig(config);} else {ZooKeeperServerMain.main(args);} }QuorumPeer 類
在 ZooKeeper 服務(wù)的集群模式啟動過程中,一個最主要的核心類是 QuorumPeer 類。我們可以將每個 QuorumPeer 類的實例看作集群中的一臺服務(wù)器。在 ZooKeeper 集群模式的運行中,一個 QuorumPeer 類的實例通常具有 3 種狀態(tài),分別是參與 Leader 節(jié)點的選舉、作為 Follow 節(jié)點同步 Leader 節(jié)點的數(shù)據(jù),以及作為 Leader 節(jié)點管理集群中的 Follow 節(jié)點。
介紹完 QuorumPeer 類后,下面我們看一下在 ZooKeeper 服務(wù)的啟動過程中,針對 QuorumPeer 類都做了哪些工作。如下面的代碼所示,在一個 ZooKeeper 服務(wù)的啟動過程中,首先調(diào)用 runFromConfig 函數(shù)將服務(wù)運行過程中需要的核心工具類注冊到 QuorumPeer 實例中去。
這些核心工具就是我們在單機(jī)版服務(wù)的啟動中介紹的諸如 FileTxnSnapLog 數(shù)據(jù)持久化類、ServerCnxnFactory 類 NIO 工廠方法等。這之后還需要配置服務(wù)器地址列表、Leader 選舉算法、會話超時時間等參數(shù)到 QuorumPeer 實例中。
public void runFromConfig(QuorumPeerConfig config){ServerCnxnFactory cnxnFactory = null;ServerCnxnFactory secureCnxnFactory = null;...quorumPeer = getQuorumPeer()quorumPeer.setElectionType(config.getElectionAlg());quorumPeer.setCnxnFactory(cnxnFactory);... }與開篇中提到的一般構(gòu)建集群的方式不同,ZooKeeper 將集群中的機(jī)器分為 Leader 、 Follow 、Obervser 三種角色,每種角色服務(wù)器在集群中起到的作用都各不相同。
比如 Leader 角色服務(wù)器主要負(fù)責(zé)處理客戶端發(fā)送的數(shù)據(jù)變更等事務(wù)性請求操作,并管理協(xié)調(diào)集群中的 Follow 角色服務(wù)器。
而 Follow 服務(wù)器則主要處理客戶端的獲取數(shù)據(jù)等非事務(wù)性請求操作。
Observer 角色服務(wù)器的功能和 Follow 服務(wù)器相似,唯一的不同就是不參與 Leader 頭節(jié)點服務(wù)器的選舉工作。
在 ZooKeeper 中的這三種角色服務(wù)器,在服務(wù)啟動過程中也有各自的不同,下面我們就以 Leader 角色服務(wù)器的啟動和 Follow 服務(wù)器服務(wù)的啟動過程來看一下各自的底層實現(xiàn)原理。
Leader 服務(wù)器啟動過程
在 ZooKeeper 集群中,Leader 服務(wù)器負(fù)責(zé)管理集群中其他角色服務(wù)器,以及處理客戶端的數(shù)據(jù)變更請求。因此,在整個 ZooKeeper 服務(wù)器中,Leader 服務(wù)器非常重要。所以在整個 ZooKeeper 集群啟動過程中,首先要先選舉出集群中的 Leader 服務(wù)器。
在 ZooKeeper 集群選舉 Leader 節(jié)點的過程中,首先會根據(jù)服務(wù)器自身的服務(wù)器 ID(SID)、最新的 ZXID、和當(dāng)前的服務(wù)器 epoch (currentEpoch)這三個參數(shù)來生成一個選舉標(biāo)準(zhǔn)。之后,ZooKeeper 服務(wù)會根據(jù) zoo.cfg 配置文件中的參數(shù),選擇參數(shù)文件中規(guī)定的 Leader 選舉算法,進(jìn)行 Leader 頭節(jié)點的選舉操作。
而在 ZooKeeper 中提供了三種 Leader 選舉算法,分別是
- LeaderElection
- AuthFastLeaderElection
- FastLeaderElection
在我們?nèi)粘i_發(fā)過程中,可以通過在 zoo.cfg 配置文件中使用 electionAlg 參數(shù)屬性來制定具體要使用的算法類型。
在 ZooKeeper 集群模式下服務(wù)啟動后。首先會創(chuàng)建用來選舉 Leader 節(jié)點的工具類 QuorumCnxManager 。
下面這段代碼給出了 QuorumCnxManager 在創(chuàng)建實例的時候首先要實例化 Listener 對象用于監(jiān)聽 Leader 選舉端口。
package org.apache.zookeeper.server.quorum; public class QuorumCnxManager { ...public QuorumCnxManager(QuorumPeer self) {String cnxToValue = System.getProperty("zookeeper.cnxTimeout")listener = new Listener();listener.setName("QuorumPeerListener");}... }而在 ZooKeeper 中,Leader 選舉的大概過程,總體說來就是在集群中的所有機(jī)器中直接進(jìn)行一次選舉投票,選舉出一個最適合的機(jī)器作為 Leader 節(jié)點。
而具體的評價標(biāo)準(zhǔn)就是我們上面提到的三種選舉算法。而從 3.4.0 版本開始,ZooKeeper 只支持 FastLeaderElection 這一種選舉算法。同時沒有被選舉為 Leader 節(jié)點的機(jī)器則作為 Follow 或 Observer 節(jié)點機(jī)器存在。
Follow 服務(wù)器啟動過程
現(xiàn)在,我們已經(jīng)選舉出 ZooKeeper 集群模式下的 Leader 節(jié)點機(jī)器了。我們再看一下 Follow 節(jié)點機(jī)器在 ZooKeeper 集群模式下服務(wù)器的啟動過程。
在服務(wù)器的啟動過程中,Follow 機(jī)器的主要工作就是和 Leader 節(jié)點進(jìn)行數(shù)據(jù)同步和交互。當(dāng) Leader 機(jī)器啟動成功后,Follow 節(jié)點的機(jī)器會收到來自 Leader 節(jié)點的啟動通知。而該通知則是通過 LearnerCnxAcceptor 類來實現(xiàn)的。該類就相當(dāng)于一個接收器。專門用來接收來自集群中 Leader 節(jié)點的通知信息。
下面這段代碼中 LearnerCnxAcceptor 類首先初始化要監(jiān)聽的 Leader 服務(wù)器地址和設(shè)置收到監(jiān)聽的處理執(zhí)行方法等操作 。
class LearnerCnxAcceptor extends ZooKeeperCriticalThread {private volatile boolean stop = false;public LearnerCnxAcceptor() {super("LearnerCnxAcceptor-" + ss.getLocalSocketAddress(), zk.getZooKeeperServerListener());}}在接收到來自 Leader 服務(wù)器的通知后,Follow 服務(wù)器會創(chuàng)建一個 LearnerHandler 類的實例,用來處理與 Leader 服務(wù)器的數(shù)據(jù)同步等操作。
package org.apache.zookeeper.server.quorum; public class LearnerHandler extends ZooKeeperThread {protected final Socket sock;final Leader leader;... }在完成數(shù)據(jù)同步后,一個 ZooKeeper 服務(wù)的集群模式下啟動的關(guān)鍵步驟就完成了,整個服務(wù)就處于運行狀態(tài),可以對外提供服務(wù)了。
小結(jié)
主要學(xué)習(xí)了 ZooKeeper 集群模式的啟動過程和底層實現(xiàn)。與一般的集群架構(gòu)不同,ZooKeeper 集群模式把其中的機(jī)器分成 Leader 、Follow 、Obsever 三種角色。
當(dāng)作為 Leader 節(jié)點的機(jī)器失效時,系統(tǒng)會根據(jù)配置文件中的選舉算法產(chǎn)生新的節(jié)點。這種方式避免了一般集群模式中產(chǎn)生的單點失效等問題。
那在我們?nèi)粘J褂?ZooKeeper 集群服務(wù)器的時候,集群中的機(jī)器個數(shù)應(yīng)該如何選擇?
答案是最好使用奇數(shù)原則,最小的集群配置應(yīng)該是三個服務(wù)器或者節(jié)點。而如果采用偶數(shù),在 Leader 節(jié)點選舉投票的過程中就不滿足大多數(shù)原則,這時就產(chǎn)生“腦裂”這個問題。
總結(jié)
以上是生活随笔為你收集整理的Apache ZooKeeper -从初始化到对外提供服务的过程解析( 集群模式 )的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Apache ZooKeeper - Z
- 下一篇: Keepalived - Keepal