帶着問題擼源碼系列-zookeeper-客戶端發寫請求,最終怎麼通過2PC同步到集羣所有機器?

問題

帶着問題擼源碼系列-zookeeper-客戶端發寫請求,最終怎麼通過2PC同步到集羣所有機器?

猜測

we all know the 2PC, but how exactly does it work?

理論上,就是leader接收到請求,然後發給Prepare,讓小夥伴們準備好,過半數人回覆ok了之後,leader回覆客戶端,然後再發Commit請求讓小夥伴們真正提交

源碼

Follower接收到客戶端的寫請求,會先根據責任鏈調下一個Processor,然後把寫請求轉發給Leader。

leader接收到轉發的寫請求,然後會怎麼樣?那就得研究Leader的責任鏈了。。

所以我們先找Leader的責任鏈:
org.apache.zookeeper.server.quorum.LeaderZooKeeperServer
上來文件頭部的註釋就有相關的說明了:

/**
 *
 * Just like the standard ZooKeeperServer. We just replace the request
 * processors: PrepRequestProcessor -> ProposalRequestProcessor ->
 * CommitProcessor -> Leader.ToBeAppliedRequestProcessor ->
 * FinalRequestProcessor
 */

PrepRequestProcessor -> ProposalRequestProcessor -> CommitProcessor -> Leader.ToBeAppliedRequestProcessor -> FinalRequestProcessor

所以我們可以從PrepRequestProcessor開始看了:
在這裏插入圖片描述

不斷地從submittedRequests中取Request。最後調用pRequest(request),來到下一個Processor,斷點打起來~

ProposalRequest
在這裏插入圖片描述

走else邏輯直接調用了nextProcessor

那就到CommitProcessor
在這裏插入圖片描述
因爲是寫請求,走if分支,QueuedWriteRequest隊列中加入了請求。

然後找消費這個隊列的地方:
在這裏插入圖片描述
這裏查了一下消費到的是不是本地的寫請求。
注:如果是本地的寫請求,說明是leader直接接收到寫請求。我們認爲沒走這個分支。(在這打個斷點,理論上不應該走到這)

斷點調試

server1、2、3順序啓動,server2是leader,debug方式啓動server2

client連到server2,直接給leader發請求 create /t2

!!!!!!!這裏要特別注意,在調試的過程中我們啓動的server2本來是leader的,調試經常導致斷線,斷線之後server2就不是leader了,得特別注意!

爲了避免這種情況,我們把server3幹掉;這樣,如果server2超時,只剩下server1,無法對外提供服務;server2活過來的話仍然是leader

先來到PrepRequestProcessor
在這裏插入圖片描述
責任鏈到下一個Processor
在這裏插入圖片描述
來到ProposalRequestProcessor
在這裏插入圖片描述

調用責任鏈下一個Processor,來到CommitProcessor

請求加入到pendingRequests
在這裏插入圖片描述

來到Leader,發送Propose請求
在這裏插入圖片描述
點收選票,這時候收到了來自與自己和server1的ack
在這裏插入圖片描述
在這裏插入圖片描述

在這裏插入圖片描述

然後來到了leader的commit
在這裏插入圖片描述

再從pendingRequest中取出了我們的請求
在這裏插入圖片描述

最後來到FinalRequestProcessor,寫入硬盤

回答問題

理論是正確的!後面再細化一下流程

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章