Zookeeper之領(lǐng)導(dǎo)者選舉初始化源碼分析

image.png
Zookeeper集群?jiǎn)?dòng)配置

1、配置文件
創(chuàng)建三個(gè)配置文件conf\zoo_sample.cfg、conf\zoo_sample2.cfg、conf\zoo_sample3.cfg


image.png

只有dataDir和clientPort對(duì)應(yīng)不同的服務(wù)端數(shù)據(jù)存儲(chǔ)位置及客戶端連接端口


image.png

在dataDir文件夾下需要分別創(chuàng)建myid文件,用來(lái)存儲(chǔ)server后面的序號(hào)1、2、3。(例如server.1=127.0.0.1:12881:13881的1)
image.png

2、三個(gè)服務(wù)端

QuorumPeerMain對(duì)應(yīng)conf\zoo_sample.cfg啟動(dòng)


image.png

QuorumPeerMain3對(duì)應(yīng)conf\zoo_sample3.cfg啟動(dòng)
image.png

QuorumPeerMain2對(duì)應(yīng)conf\zoo_sample2.cfg啟動(dòng)
3、兩個(gè)客戶端配置
加個(gè) -D:zoocfg=D:\workspase\zookeeper-master\conf\zoo_sample.cfg 對(duì)于不同服務(wù)端的客戶端(對(duì)應(yīng)不同端口)連接
image.png

集群?jiǎn)?dòng)

1、isDistributed判斷是否以集群方式啟動(dòng)
org.apache.zookeeper.server.quorum.QuorumPeerConfig#isDistributed


image.png

standaloneEnabled=true(默認(rèn)是false,是非集群)也可以啟動(dòng)
votingMembers參與投票數(shù)量大于1,也是集群?jiǎn)?dòng)。
可以算出過(guò)半值half=1(當(dāng)以三臺(tái)啟動(dòng)3/2=1)
2、initializeAndRun初始化集群
org.apache.zookeeper.server.quorum.QuorumPeerMain#initializeAndRun
這里便是根據(jù)isDistributed來(lái)判斷是否以集群?jiǎn)?dòng),與單機(jī)啟動(dòng)的區(qū)別


image.png

3、runFromConfig
org.apache.zookeeper.server.quorum.QuorumPeerMain#runFromConfig
①、ServerCnxnFactory創(chuàng)建與單機(jī)相同
image.png

②、創(chuàng)建quorumPeer對(duì)象,并給參數(shù)賦值
創(chuàng)建quorumPeer對(duì)象,并給參數(shù)賦值。從config讀取到quorumPeer中,下面是對(duì)myid賦值


image.png

③、quorumPeer.start 啟動(dòng)
image.png

initialize 初始化、JvmPauseMonitor賦值、start 啟動(dòng)、join 阻塞
4、QuorumPeer#start
org.apache.zookeeper.server.quorum.QuorumPeer#start
image.png

主要步驟:
①、loadDataBase()加載數(shù)據(jù)
②、startServerCnxnFactory 用來(lái)開(kāi)啟acceptThread、SelectorThread和workerPool線程池
③、開(kāi)啟領(lǐng)導(dǎo)者選舉startLeaderElection
④、開(kāi)啟JVM監(jiān)控線程startJvmPauseMonitor
⑤、調(diào)用父類super.start();進(jìn)行領(lǐng)導(dǎo)者選舉

初始化領(lǐng)導(dǎo)者選舉相關(guān)的線程和隊(duì)列

1、startLeaderElection


image.png

①、創(chuàng)建當(dāng)前選票currentVote
②、創(chuàng)建選舉方式createElectionAlgorithm
2、createElectionAlgorithm
org.apache.zookeeper.server.quorum.QuorumPeer#createElectionAlgorithm
目前選舉方式只有electionAlgorithm=3


image.png

image.png

這個(gè)方法創(chuàng)建了以下三個(gè)對(duì)象:

①、創(chuàng)建QuorumCnxManager對(duì)象
②、QuorumCnxManager.Listener
③、FastLeaderElection

1、創(chuàng)建QuorumCnxManager對(duì)象

這個(gè)類是一個(gè)使用TCP實(shí)現(xiàn)用于領(lǐng)導(dǎo)者選舉的連接管理器類??梢院?jiǎn)單理解為一個(gè)處理Socket的傳輸層類
org.apache.zookeeper.server.quorum.QuorumCnxManager#QuorumCnxManager


image.png

創(chuàng)建recvQueue、queueSendMap、senderWorkerMap等屬性對(duì)象


image.png
2、創(chuàng)建QuorumCnxManager.Listener對(duì)象

Listener的創(chuàng)建和啟動(dòng)


image.png

a、run
org.apache.zookeeper.server.quorum.QuorumCnxManager.Listener#run


image.png

b、啟動(dòng)ListenerHandler線程
org.apache.zookeeper.server.quorum.QuorumCnxManager.Listener.ListenerHandler#run
image.png

c、acceptConnections
org.apache.zookeeper.server.quorum.QuorumCnxManager.Listener.ListenerHandler#acceptConnections
開(kāi)啟服務(wù)端serverSocket,等待客戶端連接。阻塞在serverSocket.accept()方法


image.png
服務(wù)端間的連接

當(dāng)再開(kāi)一臺(tái),則會(huì)進(jìn)行相互連接。阻塞在serverSocket.accept()的方法這里將會(huì)繼續(xù)往下執(zhí)行。13881和13883端口用來(lái)進(jìn)行領(lǐng)導(dǎo)者選舉。
server.1=127.0.0.1:12881:13881
server.3=127.0.0.1:12883:13883


image.png

表示:由sid=1的向sid=3的連接,則會(huì)關(guān)閉當(dāng)前sid=1連接的sid=3的socket。sid=3的會(huì)向sid=1進(jìn)行連接
1、acceptConnections
接受連接
org.apache.zookeeper.server.quorum.QuorumCnxManager.Listener.ListenerHandler#acceptConnections


image.png

2、receiveConnection
處理連接
org.apache.zookeeper.server.quorum.QuorumCnxManager#receiveConnection
image.png

3、handleConnection
org.apache.zookeeper.server.quorum.QuorumCnxManager#handleConnection
①、通過(guò)網(wǎng)絡(luò)連接獲取數(shù)據(jù)sid,獲取sid表示是那一臺(tái)連過(guò)來(lái)的


image.png

②、關(guān)閉小的sid向大的sid的socket連接
如果當(dāng)前sid比連過(guò)來(lái)的大(sid < self.getId()表示當(dāng)前sid=3的是服務(wù)端),由sid=1的向sid=3的連接,則會(huì)關(guān)閉當(dāng)前sid=1連接的sid=3的socket。上圖所示。
image.png

③、大的sid與小的sid建立socket連接(服務(wù)端是小的sid=1)
關(guān)閉sid=1向sid=3的socket后,建立sid=3向sid=1建立連接(即大的sid向小的sid連接)
image.png

4、connectOne 主動(dòng)建立socket連接
org.apache.zookeeper.server.quorum.QuorumCnxManager#connectOne
image.png

5、initiateConnectionAsync
org.apache.zookeeper.server.quorum.QuorumCnxManager#initiateConnectionAsync
image.png

6、執(zhí)行QuorumConnectionReqThread線程run方法
org.apache.zookeeper.server.quorum.QuorumCnxManager#initiateConnection
image.png

7、initiateConnection
建立socket連接
org.apache.zookeeper.server.quorum.QuorumCnxManager#initiateConnection


image.png

image.png

8、startConnection
org.apache.zookeeper.server.quorum.QuorumCnxManager#startConnection
image.png

image.png

image.png

開(kāi)啟SendWorker、RecvWorker線程。并把SendWorker與sid放入到senderWorkerMap。創(chuàng)建queueSendMap集合
9、SendWorker#run
org.apache.zookeeper.server.quorum.QuorumCnxManager.SendWorker#run
image.png

image.png

從queueSendMap獲取并發(fā)送給其他服務(wù)
image.png

org.apache.zookeeper.server.quorum.QuorumCnxManager.SendWorker#send
image.png

10、RecvWorker#run
org.apache.zookeeper.server.quorum.QuorumCnxManager.RecvWorker#run
讀取并添加到recvQueue
image.png
3、創(chuàng)建FastLeaderElection對(duì)象

1、FastLeaderElection
org.apache.zookeeper.server.quorum.FastLeaderElection#FastLeaderElection


image.png

2、starter
org.apache.zookeeper.server.quorum.FastLeaderElection#starter
創(chuàng)建sendqueue、recvqueue隊(duì)列。Messenger對(duì)象


image.png

3、Messenger
org.apache.zookeeper.server.quorum.FastLeaderElection.Messenger#Messenger
創(chuàng)建WorkerSender并封裝成wsThread線程,創(chuàng)建WorkerReceiver并封裝成wrThread
image.png

4、FastLeaderElection#start
org.apache.zookeeper.server.quorum.FastLeaderElection#start


image.png

5、Messenger#start
org.apache.zookeeper.server.quorum.FastLeaderElection.Messenger#start
image.png

啟動(dòng)WorkerSender和WorkerReceiver
6、WorkerSender#run
org.apache.zookeeper.server.quorum.FastLeaderElection.Messenger.WorkerSender#run
image.png

從sendqueue發(fā)送隊(duì)列取出并處理
org.apache.zookeeper.server.quorum.FastLeaderElection.Messenger.WorkerSender#process
image.png

自己發(fā)送給自己選票
image.png

org.apache.zookeeper.server.quorum.QuorumCnxManager#addToRecvQueue
添加到recvQueue


image.png

7、WorkerReceiver#run
org.apache.zookeeper.server.quorum.FastLeaderElection.Messenger.WorkerReceiver#run
從recvQueue獲取得到Message response對(duì)象
image.png

把發(fā)送給其他節(jié)點(diǎn)的投票信息封裝成ToSend對(duì)象放入到sendqueue隊(duì)列
image.png

image.png

總結(jié):

本章主要分析了領(lǐng)導(dǎo)者選舉的初始化。
在初始化過(guò)程中,主要?jiǎng)?chuàng)建了三個(gè)對(duì)象
1、QuorumCnxManager 這個(gè)類的創(chuàng)建的作用是創(chuàng)建與Socket底層交互的相關(guān)線程和隊(duì)列
SendWorker和RecvWorker線程,recvQueue隊(duì)列、queueSendMap和senderWorkerMap集合。
2、QuorumCnxManager.Listener 用來(lái)處理領(lǐng)導(dǎo)者選舉的服務(wù)端的連接
3、FastLeaderElection 快速領(lǐng)導(dǎo)者選舉工具類,創(chuàng)建了與領(lǐng)導(dǎo)者選舉相關(guān)的線程和集合
WorkerSender和WorkerReceiver線程,sendqueue和recvqueue隊(duì)列

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
禁止轉(zhuǎn)載,如需轉(zhuǎn)載請(qǐng)通過(guò)簡(jiǎn)信或評(píng)論聯(lián)系作者。

友情鏈接更多精彩內(nèi)容