关于ZooKeeper的两点思考
?群首節點commit消息分兩步:1. 發送proposal 2. 收到超半數ack再發送commit廣播。
思考1: 場景如下,一個客戶端依次執行了兩條命令 W1 R1(使用異步),先寫后讀。是否存在這種情況:W1請求在上述的 proposal和ack未完成或者已完成但客戶端連接的服務器未commit,此時讀的可能仍然是老數據?
答:是的,ZooKeeper不能保證讀的強一致性。
思考2:群首節點依次廣播兩條proposal P1 P2。假如跟隨節點對這兩個proposal皆ACK但是由于網絡原因導致P2 先一步 到達群首(考慮極端情況,所有P1的ACK都晚到),那么是否使得ZooKeeper不能按照提交順序P1->P2執行事務了呢?而會是P2->P1?
答:不會。
?
?
群首服務器
LeaderZooKeeperServer流水線設置如上圖,對應代碼?
?
追隨者服務器如上圖,對應代碼如下,FollowerZooKeeperServer
首先,客戶端提交請求會通過FollowerRequestProcessor?
該處理器接收并處理客戶端請求。處理器會執行兩個操作:一,轉發給下一個處理器CommitProcessor;二,轉發給群首節點。
?
兩者的流水線都涉及一個重要的處理器----CommitProcessor,我們看下主要方法
這個方法主要就是不停地往隊列里塞數據,這個類繼承了Thread類,主進程如下
?
?
?
現在,我們模擬依次執行寫操作W1 W2的場景。
1. 跟隨節點收到客戶端的W1請求,CommitProcessor把請求放入阻塞隊列,此時觀察run方法,
可以發現,主要分為兩種情況: 如果是讀請求,放入toProcess列表,然后下次循環直接交給下一個處理器處理
如果是更改數據的請求,會在此處一直阻塞
此時客戶端如果向該服務器繼續發送請求,可見讀請求會通過喚醒的時刻繼續運行,而更改數據的操作依然會到上一步阻塞的地方阻塞
?假如此時跟隨節點的阻塞隊列有兩條請求 P1->P2,??nextPending=P1
2. 對于群首節點,接收到請求后會首先PrepRequestProcessor處理,依次把請求放入阻塞隊列,然后交給下一個處理器ProposalRequestProcessor處理,該處理器會準備一個提議,并把提議發送給跟隨節點,然后交給下一個處理器CommitProcessor處理
假設此時主節點廣播了 P1 P2,接下來我們繼續看follower如何處理proposal
Follower.processPacket和FollowerZooKeeperServer#logRequest
FollowerZooKeeperServer依次把P1 P2存儲到隊列pendingTxns,然后把這個提議交給SyncRequestProcessor,SyncRequestProcessor繼續傳遞給SendAckRequestProcessor向leader發送ACK消息。?
這里可以順便看下對COMMIT消息的處理
可以看到,commit之前會校驗消息的zxid是否是之前存儲的pendingTxns的事物的zxid,如果不一致則會退出重啟。
所以,在這里就有個問題:follower可以保證按照收到的消息的順序依次commit消息,那么如果群首節點發送proposal時產生了網絡問題,后發的P2先一步到達,是否會導致follower節點的commit順序是P2->P1
不會的,我們可以看下leader收到ACK后如何處理
通過Leader的processAck方法可知,如果獲取足夠的ACK,會調用下一個處理器CommitPorcessor的commit方法,在這里,假如Leader先收到了P2的足夠的ACK,則會廣播P2的commit消息,如果一段時間以后收到P1的ACK,會有一個事物id的校驗,因為先到的P2的zxid(lastCommited)大于P1的zxid所以會丟棄P1,從而只會有P2成功COMMIT。
?
而CommitProcessor的comit方法做了一件事:將請求添加到queuedRequests隊列,而這個隊列的作用是什么呢,正式前面提到的解除CommitProcessor run方法阻塞的條件
所以,不論是由于網絡的影響導致follower先收到P2->P1的proposal, 還是正常收到P1->P2的proposal但是leader卻先P2->P1的ACK,都會由于leader和follower的校驗機制確保順序的有序性。?
轉載于:https://www.cnblogs.com/liuyuchong/p/10858931.html
總結
以上是生活随笔為你收集整理的关于ZooKeeper的两点思考的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 判断浏览器是pc端还是移动端
- 下一篇: 鼠标按下改变RelativeLayout