ZooKeeper集群中的跟隨者對客戶端請求的處理流程解讀(三)
前篇簡要回顧:前篇文章講到了ZK在回復完成之后進入了接客狀態,跟隨者在監聽客戶端端口的部分接收到客戶端的請求數據包,然后開始對這個包進行處理,接下來進入了ZK對客戶端請求處理流程的核心部分。。。
本篇從ZooKeeperServer的 processPacket這個方法開始講起,也就是客戶端連接實例ServerCnxn會把數據包遞交給ZooKeeperServer的 processPacket方法,processPacket將數據包裝成ZK請求最后遞交到了processPacket方法來繼續處理:
看到實際上由ZooKeeperServer關聯的第一個客戶端請求處理器來處理的,這里講一下跟隨者的客戶端請求處理器鏈。
ZooKeeperServer定義了一個模板方法setupRequestProcessors,不同角色類型的ZK節點會有不同的實現,這里我么你看一下跟隨者是如何實現這個方法來構造客戶端請求處理器鏈的:
根據上面的處理器構造鏈邏輯,畫出了下面的處理器鏈模型,可以看到ZK跟隨者對客戶端的處理器鏈有兩條。
我 們先看看第一條鏈,SyncRequestProcessor處理器主要是用來處理ZK日志的,SyncRequestProcessor接收到日志請求 會首先將日志遞交給SyncRequestProcessor實例維護的等待隊列里面,另外SyncRequestProcessor的主線程會從這個隊 列里面拿到日志請求來處理,這里主要是將ZK事務日志寫入ZK的日志存儲結構,隨后SyncRequestProcessor將日志請求包傳遞給 SendAckRequestProcessor處理器,由SendAckRequestProcessor處理器來發送日志寫入的確認報文。
下 面來看看第二條處理器鏈,首先客戶端請求報文會遞交給FollowerRequestProcessor這個處理器,這個處理器做的事情是首先將包遞交給 下一個處理器的等待處理隊列,也就是CommitProcessor的等待處理隊列,然后判斷請求的類型,這里對sync類型的請求處理有點不同,ZK作 者解釋的意思是我們需要跟蹤當前跟隨者掛起的同步操作,因此需要將同步操作記錄下來,實現是放入跟隨者關聯的一個同步隊列里面。我們接續看跟隨者是如何處 理客戶端請求報文的,這里FollowerRequestProcessor會將寫請求轉發給Leader,如果是讀請求則直接交給下一個請求處理器即 FinalRequestProcessor來處理。
另外提一下CommitProcessor主要維護兩個隊列,queuedRequests和committedRequests:
queuedRequests用來存放客戶端的請求,包括讀、寫、同步請求,處理的時候從這個隊列里面拿數據,如果是讀請求,則直接交給下一個處理器,如果是寫請求或者同步請求,則掛起,等待Leader的確認。
committedRequests主要用來存儲Leader反饋的提交請求,即Leader確定之前掛起的某個客戶端請求可以提交了。
FinalRequestProcessor做的事情主要是客戶端請求處理的最后一個階段,如果是讀請求則將數據讀取返回給客戶端,如果是寫請求則將數據寫入ZK,如果是同步請求則則將同步后的數據返回給客戶端。
這里畫出一張圖表示一下跟隨者對客戶端請求的處理行為:
FollowerRequestProcessor的處理流程。
CommitProcessor的處理流程。
到這里,跟隨者對客戶端的請求處理流程大致已經清楚,這其中涉及到一些跟領導者的通信部分以及一些細節,下面講領導者對客戶端的請求處理流程解讀的時候會拿出來回顧一下。
來自:http://jvmplus.duapp.com/blog/view/B143730149