本文的主題就是講解Zookeeper通訊模型,本節將經過一個概要圖來講明Zookeeper的通訊模型。java
在Zookeeper整個系統中,有3中角色的服務,client、Follower、leader。其中client負責發起應用的請求,Follower接受client發起的請求,參與事務的確認過程,在leader crash後的leader選擇。而leader主要承擔事務的協調,固然leader也能夠承擔接收客戶請求的功能,爲了方便描述,後面的描述都是client與Follower之間的通訊,若是Zookeeper的配置支持leader接收client的請求,client與leader的通訊跟client與Follower的通訊模式徹底同樣。Follower與leader之間的角色可能在某一時刻進行轉換。一個Follower在leader crash掉之後可能被集羣(Quorum)的Follower選舉爲leader。而一個leader在crash後,再次加入集羣(Quorum)將做爲Follower角色存在。在一個集羣(Quorum)中,除了在選舉leader的過程當中沒有Follower和leader的區分外,其餘任什麼時候刻都只有1個leader和多個Follower。Client、Follower和leader之間的通訊架構以下:node
Client與Follower之間算法
爲了使客戶端具備較高的吞吐量,Client與Follower之間採用NIO的通訊方式。當client須要與Zookeeper service打交道時,首先讀取配置文件肯定集羣內的全部server列表,按照必定的load balance算法選取一個Follower做爲一個通訊目標。這樣client和Follower之間就有了一條由NIO模式構成的通訊通道。這條通道會一直保持到client關閉session或者由於client或Follower任一方因某種緣由異常中斷通訊鏈接。正常狀況下, client與Follower在沒有請求發起的時候都有心跳檢測。服務器
Follower與leader之間session
Follower與leader之間的通訊主要是由於Follower接收到像(create, delete, setData, setACL, createSession, closeSession, sync)這樣一些須要讓leader來協調最終結果的命令,將會致使Follower與leader之間產生通訊。因爲leader與Follower之間的關係式一對多的關係,很是適合client/server模式,所以他們之間是採用c/s模式,由leader建立一個socket server,監聽各Follower的協調請求。架構
集羣在選擇leader過程當中異步
因爲在選擇leader過程當中沒有leader,在集羣中的任何一個成員都須要與其餘全部成員進行通訊,當集羣的成員變得很大時,這個通訊量是很大的。選擇leader的過程發生在Zookeeper系統剛剛啓動或者是leader失去聯繫後,選擇leader過程當中將不能處理用戶的請求,爲了提升系統的可用性,必定要儘可能減小這個過程的時間。選擇哪一種方式讓他們可用快速獲得選擇結果呢?Zookeeper在這個過程當中採用了策略模式,可用動態插入選擇leader的算法。系統默認提供了3種選擇算法,AuthFastLeaderElection,FastLeaderElection,LeaderElection。其中AuthFastLeaderElection和LeaderElection採用UDP模式進行通訊,而FastLeaderElection仍然採用tcp/ip模式。在Zookeeper新的版本中,新增了一個learner角色,減小選擇leader的參與人數。使得選擇過程更快。通常說來Zookeeper leader的選擇過程都很是快,一般<200ms。socket
要詳細瞭解Zookeeper的通訊流程,咱們首先得了解Zookeeper提供哪些客戶端的接口,咱們按照具備相同的通訊流程的接口進行分組:tcp
Zookeeper的系統管理接口是指用來查看Zookeeper運行狀態的一些命令,他們都是具備4字母構成的命令格式。主要包括:測試
當用戶發送這些命令的到server時,因爲這些請求只與鏈接的server相關,沒有業務處理邏輯,很是簡單。Zookeeper對這些命令採用最快的效率進行處理。這些命令發送到server端只佔用一個4字節的int類型來表示不一樣命令,沒有采用字符串處理。當服務器端接收到這些命令,馬上返回結果。
Session建立
任何客戶端的業務請求都是基於session存在的前提下。Session是維持client與Follower之間的一條通訊通道,並維持他們之間從建立開始後的全部狀態。當啓動一個Zookeeper client的時候,首先按照必定的算法查找出follower, 而後與Follower創建起NIO鏈接。當鏈接創建好後,發送create session的命令,讓server端爲該鏈接建立一個維護該鏈接狀態的對象session。當server收到create session命令,先從本地的session列表中查找看是否已經存在有相同sessionId,則關閉原session從新建立新的session。建立session的過程將須要發送到Leader,再由leader通知其餘follower,大部分Follower都將此操做記錄到本地日誌再通知leader後,leader發送commit命令給全部Follower,鏈接客戶端的Follower返回建立成功的session響應。Leader與Follower之間的協調過程將在後面的作詳細講解。當客戶端成功建立好session後,其餘的業務命令就能夠正常處理了。
Zookeeper查詢命令
Zookeeper查詢命令主要用來查詢服務器端的數據,不會更改服務器端的數據。全部的查詢命令均可以即刻從client鏈接的server當即返回,不須要leader進行協調,所以查詢命令獲得的數據有多是過時數據。但因爲任何數據的修改,leader都會將更改的結果發佈給全部的Follower,所以通常說來,Follower的數據是能夠獲得及時的更新。這些查詢命令包括如下這些命令:
全部的查詢命令均可以指定watcher,經過它來跟蹤指定path的數據變化。一旦指定的數據發生變化(create,delete,modified,children_changed),服務器將會發送命令來回調註冊的watcher. Watcher詳細的講解將在Zookeeper的Watcher中單獨講解。
Zookeeper修改命令
Zookeeper修改命令主要是用來修改節點數據或結構,或者權限信息。任何修改命令都須要提交到leader進行協調,協調完成後才返回。修改命令主要包括:
咱們根據前面的通訊圖知道,任何修改命令都須要leader協調。 在leader的協調過程當中,須要3次leader與Follower之間的來回請求響應。而且在此過程當中還會涉及事務日誌的記錄,更糟糕的狀況是還有take snapshot的操做。所以此過程可能比較耗時。但Zookeeper的通訊中最大特色是異步的,若是請求是接二連三的,Zookeeper的處理是集中處理邏輯,而後批量發送,批量的大小也是有控制的。若是請求量不大,則即刻發送。這樣當負載很大時也能保證很大的吞吐量,時效性也在必定程度上進行了保證。
<!--EndFragment-->
Zookeeper經過鏈式的processor來處理業務請求,每一個processor負責處理特定的功能。不一樣的Zookeeper角色的服務器processor鏈是不同的,如下分別介紹standalone Zookeeper server, leader和Follower不一樣的processor鏈。
Zookeeper中的processor
Standalone zookeeper processor鏈
Leader processor鏈
Follower processor鏈