概述
? ? 在講清楚了《zookeeper選舉》的過程之后,突然有個疑問那就是既然完成了選舉了,那么zookeeper集群中各個角色將會如何進(jìn)入工作,以及如何應(yīng)對leader退出重新發(fā)起選舉呢?然后就繼續(xù)閱讀才有了這篇博文。
? ? 這篇博文主要想講清楚的幾個問題是:1、選舉結(jié)束后leader的任務(wù);2、選舉結(jié)束后follower和observer的任務(wù);3、leader和follower之間的交互;4、如何發(fā)起重新選舉。其實我們知道在zookeeper集群當(dāng)中選舉和通信的兩個通信是通過不同的端口去實現(xiàn)的,所以這里介紹的通信是另外一個端口的事情。
????加插一句,其實看源碼有時候你跳出代碼的細(xì)枝末節(jié)而直接問自己關(guān)鍵問題,無非就那幾個核心的知識點,只要把這幾個知識點在源代碼中得到印證并串聯(lián)起來,那么整個系統(tǒng)就打通了。當(dāng)然,看源代碼切記不要著急,因為肯定有一些地方是你忽略,宏觀上正常運轉(zhuǎn)的邏輯在代碼層面肯定是可以找到的,所以只要耐心讀下去和分析就可以了,當(dāng)然畢竟很多源碼已經(jīng)出來了很久了,已經(jīng)很多前人已經(jīng)閱讀了,可以在他們的肩膀上繼續(xù)你的理解。
基礎(chǔ)知識
????在講解正式內(nèi)容之前需要把zookeeper集群中的各個角色分清楚,這樣能夠更加方便的理解。我們之前將的選舉無非就是為了區(qū)分出leader、follower、observer三種角色,各個角色的作用如下:
Leader
? ? ? ? Leader服務(wù)器是整個zookeeper集群工作機(jī)制中的核心,其主要工作有以下兩個:
? ? ? ? 事物請求的唯一調(diào)度和處理者,保證集群事務(wù)處理的順序性。
? ? ? ? 集群內(nèi)部各個服務(wù)器的調(diào)度者。
Follower
? ? ? ??從角色名字可以看出,F(xiàn)ollower服務(wù)器是zookeeper集群狀態(tài)的跟隨者,其主要工作有以下三個:
? ? ? ? 處理客戶端非事物請求,轉(zhuǎn)發(fā)事物請求給Leader服務(wù)器。
? ? ? ? 參與事務(wù)請求Proposal的投票。
? ? ? ? 參與Leader選舉投票。
Observer
? ? ? ??和Follower唯一的區(qū)別在于,Observer不參與任何形式的投票,包括事物請求Proposal的投票和Leader選舉投票。簡單地講,Observer服務(wù)器只提供非事物服務(wù),通常用于在不影響集群事務(wù)處理能力的前提下提升集群的非事物處理能力。

????在QuorumPeer的主循環(huán)當(dāng)中,可以看到不同角色的處理邏輯,所以如果從閱讀源碼的角度出發(fā),這里就是最好的入口了,我們要講的leader、follower、observer等角色任務(wù)也是直接從這里可以跟進(jìn)去發(fā)現(xiàn)的。
leader的任務(wù)
? ? leader的主要任務(wù)主要是兩個,負(fù)責(zé)響應(yīng)client的連接以及請求,響應(yīng)follower的連接以及請求。因為前者涉及到數(shù)據(jù)的讀寫任務(wù)所以暫時沒來得及分析,主要著重講解后者。先把步驟寫清楚,最后以源碼截圖來表述整個過程
? ? leader的過程
????????1、啟動follower的acceptor線程負(fù)責(zé)接收follower的連接(肯定會有follower來連接,因為前面的選舉過程中zk集群的所有節(jié)點其實已經(jīng)啟動了)。
????????2、針對accept后的follower的socket后建立一個單獨的線程負(fù)責(zé)與follower進(jìn)行通信。
????????3、啟動zookeeper的server端,主要用于監(jiān)聽client的連接。
????????4、進(jìn)入while循環(huán)后不停的發(fā)送ping包
????leader過程源碼? ? ? ??

????1、負(fù)責(zé)啟動acceptor線程接收follower的連接

????1、判斷是否超過半數(shù)的follower進(jìn)行連接了,這個有個知識點比較繞,就是如果沒有超過半數(shù)我們就會通過connectingFollowers.wait進(jìn)行等待,那么是誰幫忙喚醒的呢?其實是針對每個follower連接我們會新建一個線程進(jìn)行處理,在這個處理過程中我們會去判斷是否達(dá)到半數(shù)從而喚醒這個主線程的wait。

1、針對每個連接創(chuàng)建的一個創(chuàng)建一個線程,然后在線程里面負(fù)責(zé)和client進(jìn)行通信。

1、每個與client通信的線程中都會嘗試去喚醒leader的線程,其實可以看出來getEpochToPropose調(diào)用的是同一個方法,也就是說會執(zhí)行notifyAll。這樣就可以喚醒leader的等待線程。

1、負(fù)責(zé)和follower進(jìn)行交互的邏輯。

1、主線程不停和follower進(jìn)行通信。
follower&observer任務(wù)
????follower(observer)的角色就是跟leader不停的通信,然后如果通信失敗那么就退出進(jìn)行重新選舉過程。當(dāng)然follower還負(fù)責(zé)接收leader的命令執(zhí)行相應(yīng)的操作。整個follower的啟動過程如下:
? ? 1、follower向leader發(fā)起連接
? ? 2、連接建議后進(jìn)行for循環(huán)負(fù)責(zé)處理leader的命令。
源碼分析

1、負(fù)責(zé)連接leader并處理leader發(fā)送的報文

1、主動連接leader并取得輸入輸出流進(jìn)行交互。

1、處理leader發(fā)送過來的命令的邏輯
follower&leader交互
? ? 這部分主要是講解清楚leader和follower在建立連接過程中的交互,直接用時序圖來說明,同時將交互之間的報文格式一并貼出來。

1、follower向leader發(fā)起連接
2、follower發(fā)送FOLLOWERINFO報文
3、leader回復(fù)LEADERINFO報文
4、follower發(fā)送ACKEPOCH報文
5、follower和leader各自繼續(xù)執(zhí)行各自邏輯
6、報文格式請參考《zookeeper-服務(wù)器角色介紹》
源碼分析

核心點在于發(fā)起連接和進(jìn)行連接注冊

1、發(fā)起連接動作

1、發(fā)送FollowerInfo報文
2、處理LeaderInfo報文
3、發(fā)送AckEpoch報文

