Apache ZooKeeper - 集群中 Follow 的作用_非事务请求的处理与 Leader 的选举分析
文章目錄
- Pre
- 非事務性請求處理過程
- 源碼分析
- 選舉過程
- 在這里插入圖片描述
- Leader 失效發現
- Leader 重新選舉
- Follow 角色變更
- 集群同步數據
- 源碼解析
- 小結
Pre
在 ZooKeeper 集群中,Leader 服務器主要負責處理來自客戶端的事務性會話請求,并在處理完事務性會話請求后,管理和協調 ZooKeeper 集群中 Follow 和 Observer 等角色服務器的數據同步。
因此,在 ZooKeeper 集群中,Leader 服務器是最為核心的服務器,一個 ZooKeeper 服務在集群模式下運行,必須存在一個 Leader 服務器。
而在 ZooKeeper 集群中,是通過崩潰選舉的方式來保證 ZooKeeper 集群能夠一直存在一個 Leader 服務器對外提供服務的。
那么在 ZooKeeper 集群選舉出 Leader 的過程中,Follow 服務器又做了哪些工作?
清楚不同狀態下服務器的處理邏輯和相關操作 ,有助于我們掌握整個 ZooKeeper 集群服務的運行過程, 使我們在日常工作中,更好地開發 ZooKeeper 相關服務,并在運維過程中快速定位問題,搭建更加高效穩定的 ZooKeeper 服務器。
非事務性請求處理過程
在 ZooKeeper 集群接收到來自客戶端的請求后,會首先判斷該會話請求的類型,如是否是事務性請求。
、
所謂事務性請求,是指 ZooKeeper 服務器執行完該條會話請求后,是否會導致執行該條會話請求的服務器的數據或狀態發生改變,進而導致與其他集群中的服務器出現數據不一致的情況。
這里我們以客戶端發起的數據節點查詢請求為例,分析一下 ZooKeeper 在處理非事務性請求時的實現過程。
當 ZooKeeper 集群接收到來自客戶端發送的查詢會話請求后,會將該客戶端請求分配給 Follow 服務器進行處理。
而在 Follow 服務器的內部,也采用了責任鏈的處理模式來處理來自客戶端的每一個會話請求。
Leader 服務器的處理鏈過程,分別包含預處理器階段、Proposal 提交處理器階段以及 final 處理器階段。
與 Leader 處理流程不同的是,在 Follow 角色服務器的處理鏈執行過程中,FollowerRequestProcessor 作為第一個處理器,主要負責篩選該條會話請求是否是事務性的會話請求。如果是事務性的會話請求,則轉發給 Leader 服務器進行操作。如果不是事務性的會話請求,則交由 Follow 服務器處理鏈上的下一個處理器進行處理。
而下一個處理器是 CommitProcessor ,該處理器的作用是對來自集群中其他服務器的事務性請求和本地服務器的提交請求操作進行匹配。匹配的方式是,將本地執行的 sumbit 提交請求,與集群中其他服務器接收到的 Commit 會話請求進行匹配,匹配完成后再交由 Follow 處理鏈上的下一個處理器進行處理。
最終,當一個客戶端會話經過 Final 處理器操作后,就完成了整個 Follow 服務器的會話處理過程,并將結果響應給客戶端。
源碼分析
ZooKeeper 集群在接收到來自客戶端的請求后,會將請求交給 Follow 服務器進行處理。而 Follow 服務器內部首先調用的是 FollowerZooKeeperServer 類,該類的作用是封裝 Follow 服務器的屬性和行為,你可以把該類當作一臺 Follow 服務器的代碼抽象。
FollowerZooKeeperServer 類繼承了 LearnerZooKeeperServer 。在一個 FollowerZooKeeperServer 類內部,定義了一個核心的 ConcurrentLinkedQueue 類型的隊列字段,用于存放接收到的會話請求。
在定義了 FollowerZooKeeperServer 類之后,在該類的 setupRequestProcessors 函數中,定義了處理責任鏈,指定了該處理鏈上的各個處理器。如下面的代碼所示,分別按順序定義了起始處理器 FollowerRequestProcessor 、提交處理器 CommitProcessor、同步處理器 SendAckRequestProcessor 以及最終處理器 FinalProcessor。
選舉過程
介紹完 Follow 服務器處理非事務性請求的過程后,接下來我們再學習一下 Follow 服務器的另一個主要的功能:在 Leader 服務器崩潰的時候,重新選舉出 Leader 服務器。
ZooKeeper 集群重新選舉 Leader 的過程本質上只有 Follow 服務器參與工作。
而在 ZooKeeper 集群重新選舉 Leader 節點的過程中主要可以分為 Leader 失效發現、重新選舉 Leader 、Follow 服務器角色變更、集群同步這幾個步驟。
Leader 失效發現
在 ZooKeeper 集群中,當 Leader 服務器失效時,ZooKeeper 集群會重新選舉出新的 Leader 服務器。也就是說,Leader 服務器的失效會觸發 ZooKeeper 開始新 Leader 服務器的選舉,那么在 ZooKeeper 集群中,又是如何發現 Leader 服務器失效的呢?
這里就要介紹到 Leader 失效發現。和之前介紹的保持客戶端活躍性的方法,它是通過客戶端定期向服務器發送 Ping 請求來實現的。
在 ZooKeeper 集群中,探測 Leader 服務器是否存活的方式與保持客戶端活躍性的方法非常相似。首先,Follow 服務器會定期向 Leader 服務器發送 網絡請求,在接收到請求后,Leader 服務器會返回響應數據包給 Follow 服務器,而在 Follow 服務器接收到 Leader 服務器的響應后,如果判斷 Leader 服務器運行正常,則繼續進行數據同步和服務轉發等工作,反之,則進行 Leader 服務器的重新選舉操作。
Leader 重新選舉
當 Follow 服務器向 Leader 服務器發送狀態請求包后,如果沒有得到 Leader 服務器的返回信息,這時,如果是集群中個別的 Follow 服務器發現返回錯誤,并不會導致 ZooKeeper 集群立刻重新選舉 Leader 服務器,而是將該 Follow 服務器的狀態變更為 LOOKING 狀態,并向網絡中發起投票,當 ZooKeeper 集群中有更多的機器發起投票,最后當投票結果滿足多數原則的情況下。ZooKeeper 會重新選舉出 Leader 服務器。
Follow 角色變更
在 ZooKeeper 集群中,Follow 服務器作為 Leader 服務器的候選者,當被選舉為 Leader 服務器之后,其在 ZooKeeper 集群中的 Follow 角色,也隨之發生改變。也就是要轉變為 Leader 服務器,并作為 ZooKeeper 集群中的 Leader 角色服務器對外提供服務。
集群同步數據
在 ZooKeeper 集群成功選舉 Leader 服務器,并且候選 Follow 服務器的角色變更后。為避免在這期間導致的數據不一致問題,ZooKeeper 集群在對外提供服務之前,會通過 Leader 角色服務器管理同步其他角色服務器.
源碼解析
首先,ZooKeeper 集群會先判斷 Leader 服務器是否失效,而判斷的方式就是 Follow 服務器向 Leader 服務器發送請求包,之后 Follow 服務器接收到響應數據后,進行解析,如下面的代碼所示,Follow 服務器會根據返回的數據,判斷 Leader 服務器的運行狀態,如果返回的是 LOOKING 關鍵字,表明與集群中 Leader 服務器無法正常通信。
switch (rstate) {case 0:ackstate = QuorumPeer.ServerState.LOOKING;break;case 1:ackstate = QuorumPeer.ServerState.FOLLOWING;break;case 2:ackstate = QuorumPeer.ServerState.LEADING;break;case 3:ackstate = QuorumPeer.ServerState.OBSERVING;break;default:continue;之后,在 ZooKeeper 集群選舉 Leader 服務器時,是通過 FastLeaderElection 類實現的。該類實現了 TCP 方式的通信連接,用于在 ZooKeeper 集群中與其他 Follow 服務器進行協調溝通。
FastLeaderElection 類繼承了 Election 接口,定義其是用來進行選舉的實現類。而在其內部,又定義了選舉通信相關的一些配置參數,比如 finalizeWait 最終等待時間、最大通知間隔時間 maxNotificationInterval 等。
在選舉的過程中,首先調用 ToSend 函數向 ZooKeeper 集群中的其他角色服務器發送本機的投票信息,其他服務器在接收投票信息后,會對投票信息進行有效性驗證等操作,之后 ZooKeeper 集群統計投票信息,如果過半數的機器投票信息一致,則集群就重新選出新的 Leader 服務器。
static public class ToSend {static enum mType {crequest, challenge, notification, ack}ToSend(mType type,long leader,long zxid,long electionEpoch,ServerState state,long sid,long peerEpoch,byte[] configData) {this.leader = leader;this.zxid = zxid;this.electionEpoch = electionEpoch;this.state = state;this.sid = sid;this.peerEpoch = peerEpoch;this.configData = configData;}小結
我們知道在 ZooKeeper 集群中 Follow 服務器的功能和作用。Follow 服務器在 ZooKeeper 集群服務運行的過程中,負責處理來自客戶端的查詢等非事務性的請求操作。當 ZooKeeper 集群中舊的 Leader 服務器失效時,作為投票者重新選舉出新的 Leader 服務器。
這里我們要注意一個問題,那就是在重新選舉 Leader 服務器的過程中,ZooKeeper 集群理論上是無法進行事務性的請求處理的。因此,發送到 ZooKeeper 集群中的事務性會話會被掛起,暫時不執行,等到選舉出新的 Leader 服務器后再進行操作。
總結
以上是生活随笔為你收集整理的Apache ZooKeeper - 集群中 Follow 的作用_非事务请求的处理与 Leader 的选举分析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Apache ZooKeeper - 集
- 下一篇: Apache ZooKeeper - 集