zookeeper系列之通訊模型(轉)

本文的主題就是講解Zookeeper通訊模型,本節將經過一個概要圖來講明Zookeeper的通訊模型。java

 

 

Zookeeper的通訊架構

在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的通訊流程,咱們首先得了解Zookeeper提供哪些客戶端的接口,咱們按照具備相同的通訊流程的接口進行分組:tcp

 

Zookeeper系統管理命令

Zookeeper的系統管理接口是指用來查看Zookeeper運行狀態的一些命令,他們都是具備4字母構成的命令格式。主要包括:測試

  1. ruok:發送此命令能夠測試zookeeper是否運行正常。
  2. dump:dump server端全部存活session的Ephemeral(臨時)node信息。
  3. stat:獲取鏈接server的服務器端的狀態及鏈接該server的全部客服端的狀態信息。
  4. reqs: 獲取當前客戶端已經提交但還未返回的請求。
  5. stmk:開啓或關閉Zookeeper的trace level.
  6. gtmk:獲取當前Zookeeper的trace level是否開啓。
  7. envi: 獲取Zookeeper的java相關的環境變量。
  8. srst:重置server端的統計狀態

當用戶發送這些命令的到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的數據是能夠獲得及時的更新。這些查詢命令包括如下這些命令:

  1. exists:判斷指定path的node是否存在,若是存在則返回true,不然返回false.
  2. getData:從指定path獲取該node的數據
  3. getACL:獲取指定pathACL
  4. getChildren:獲取指定pathnode的全部孩子結點。

全部的查詢命令均可以指定watcher,經過它來跟蹤指定path的數據變化。一旦指定的數據發生變化(create,delete,modified,children_changed),服務器將會發送命令來回調註冊的watcher. Watcher詳細的講解將在Zookeeper的Watcher中單獨講解。

 

Zookeeper修改命令

Zookeeper修改命令主要是用來修改節點數據或結構,或者權限信息。任何修改命令都須要提交到leader進行協調,協調完成後才返回。修改命令主要包括:

  1. 1.   createSession請求server建立一個session
  2. 2.   create建立一個節點
  3. 3.   delete刪除一個節點
  4. 4.   setData修改一個節點的數據
  5. 5.   setACL修改一個節點的ACL
  6. 6.   closeSession請求server關閉session

咱們根據前面的通訊圖知道,任何修改命令都須要leader協調。 在leader的協調過程當中,須要3次leader與Follower之間的來回請求響應。而且在此過程當中還會涉及事務日誌的記錄,更糟糕的狀況是還有take snapshot的操做。所以此過程可能比較耗時。但Zookeeper的通訊中最大特色是異步的,若是請求是接二連三的,Zookeeper的處理是集中處理邏輯,而後批量發送,批量的大小也是有控制的。若是請求量不大,則即刻發送。這樣當負載很大時也能保證很大的吞吐量,時效性也在必定程度上進行了保證。

 

zookeeper server端的業務處理-processor鏈

 

<!--EndFragment-->

Zookeeper經過鏈式的processor來處理業務請求,每一個processor負責處理特定的功能。不一樣的Zookeeper角色的服務器processor鏈是不同的,如下分別介紹standalone Zookeeper server, leader和Follower不一樣的processor鏈。

 

Zookeeper中的processor

  1. AckRequestProcessor:當leader從向Follower發送proposal後,Follower將發送一個Ack響應,leader收到Ack響應後,將會調用這個Processor進行處理。它主要負責檢查請求是否已經達到了多數Follower的確認,若是知足條件,則提交commitProcessor進行commit處理
  2. CommitProcessor:從commited隊列中處理已經由leader協調好並commit的請求或者從請求隊列中取出那些無需leader協調的請求進行下一步處理。
  3. FinalRequestProcessor:任何請求的處理都須要通過這個processor,這是請求處理的最後一個Processor,主要負責根據不一樣的請求包裝不一樣的類型的響應包。固然Follower與leader之間協調後的請求因爲沒有client鏈接,將不須要發送響應(代碼體如今if (request.cnxn == null) {return;})。
  4. FollowerRequestProcessor:Follower processor鏈上的第一個,主要負責將修改請求和同步請求發往leader進行協調。
  5. PrepRequestProcessor:在leader和standalone server上做爲第一Processor,主要做用對於全部的修改命令生成changelog。
  6. ProposalRequestProcessor:leader用來將請求包裝爲proposal向Follower請求確認。
  7. SendAckRequestProcessor:Follower用來向leader發送Ack響應的處理。
  8. SyncRequestProcessor:負責將已經commit的事務寫到事務日誌以及take snapshot.
  9. ToBeAppliedRequestProcessor:負責將tobeApplied隊列的中request轉移到下一個請求進行處理。

 

Standalone zookeeper processor鏈

 

 

 

Leader processor鏈

 

Follower processor鏈

 

 

 

轉自 http://zoutm.iteye.com/blog/708447

相關文章
相關標籤/搜索