日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【分布式】Zookeeper请求处理

發(fā)布時間:2025/3/19 编程问答 51 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【分布式】Zookeeper请求处理 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

一、前言

  在前面學(xué)習(xí)了Zookeeper中服務(wù)器的三種角色及其之間的通信,接著學(xué)習(xí)對于客戶端的一次請求,Zookeeper是如何進(jìn)行處理的。

二、請求處理

  2.1 會話創(chuàng)建請求

  Zookeeper服務(wù)端對于會話創(chuàng)建的處理,大體可以分為請求接收、會話創(chuàng)建、預(yù)處理、事務(wù)處理、事務(wù)應(yīng)用和會話響應(yīng)六大環(huán)節(jié),其大體流程如


  1. 請求接收

  (1) I/O層接收來自客戶端的請求。NIOServerCnxn維護(hù)每一個客戶端連接,客戶端與服務(wù)器端的所有通信都是由NIOServerCnxn負(fù)責(zé),其負(fù)責(zé)統(tǒng)一接收來自客戶端的所有請求,并將請求內(nèi)容從底層網(wǎng)絡(luò)I/O中完整地讀取出來。

  (2) 判斷是否是客戶端會話創(chuàng)建請求。每個會話對應(yīng)一個NIOServerCnxn實體,對于每個請求,Zookeeper都會檢查當(dāng)前NIOServerCnxn實體是否已經(jīng)被初始化,如果尚未被初始化,那么就可以確定該客戶端一定是會話創(chuàng)建請求。

  (3) 反序列化ConnectRequest請求。一旦確定客戶端請求是否是會話創(chuàng)建請求,那么服務(wù)端就可以對其進(jìn)行反序列化,并生成一個ConnectRequest載體。

  (4) 判斷是否是ReadOnly客戶端。如果當(dāng)前Zookeeper服務(wù)器是以ReadOnly模式啟動,那么所有來自非ReadOnly型客戶端的請求將無法被處理。因此,服務(wù)端需要先檢查是否是ReadOnly客戶端,并以此來決定是否接受該會話創(chuàng)建請求。

  (5) 檢查客戶端ZXID。正常情況下,在一個Zookeeper集群中,服務(wù)端的ZXID必定大于客戶端的ZXID,因此若發(fā)現(xiàn)客戶端的ZXID大于服務(wù)端ZXID,那么服務(wù)端不接受該客戶端的會話創(chuàng)建請求。

  (6) 協(xié)商sessionTimeout。在客戶端向服務(wù)器發(fā)送超時時間后,服務(wù)器會根據(jù)自己的超時時間限制最終確定該會話超時時間,這個過程就是sessionTimeout協(xié)商過程。

  (7) 判斷是否需要重新激活創(chuàng)建會話。服務(wù)端根據(jù)客戶端請求中是否包含sessionID來判斷該客戶端是否需要重新創(chuàng)建會話,若客戶單請求中包含sessionID,那么就認(rèn)為該客戶端正在進(jìn)行會話重連,這種情況下,服務(wù)端只需要重新打開這個會話,否則需要重新創(chuàng)建。

  2. 會話創(chuàng)建

  (1) 為客戶端生成sessionID。在為客戶端創(chuàng)建會話之前,服務(wù)端首先會為每個客戶端分配一個sessionID,服務(wù)端為客戶端分配的sessionID是全局唯一的。

  (2) 注冊會話。向SessionTracker中注冊會話,SessionTracker中維護(hù)了sessionsWithTimeout和sessionsById,在會話創(chuàng)建初期,會將客戶端會話的相關(guān)信息保存到這兩個數(shù)據(jù)結(jié)構(gòu)中。

  (3) 激活會話。激活會話涉及Zookeeper會話管理的分桶策略,其核心是為會話安排一個區(qū)塊,以便會話清理程序能夠快速高效地進(jìn)行會話清理。

  (4) 生成會話密碼。服務(wù)端在創(chuàng)建一個客戶端會話時,會同時為客戶端生成一個會話密碼,連同sessionID一同發(fā)給客戶端,作為會話在集群中不同機(jī)器間轉(zhuǎn)移的憑證。

  3. 預(yù)處理

  (1) 將請求交給PrepRequestProcessor處理器處理。在提交給第一個請求處理器之前,Zookeeper會根據(jù)該請求所屬的會話,進(jìn)行一次激活會話操作,以確保當(dāng)前會話處于激活狀態(tài),完成會話激活后,則提交請求至處理器。

  (2) 創(chuàng)建請求事務(wù)頭。對于事務(wù)請求,Zookeeper會為其創(chuàng)建請求事務(wù)頭,服務(wù)端后續(xù)的請求處理器都是基于該請求頭來識別當(dāng)前請求是否是事務(wù)請求,請求事務(wù)頭包含了一個事務(wù)請求最基本的一些信息,包括sessionID、ZXID(事務(wù)請求對應(yīng)的事務(wù)ZXID)、CXID(客戶端的操作序列)和請求類型(如create、delete、setData、createSession等)等。

  (3) 創(chuàng)建請求事務(wù)體。由于此時是會話創(chuàng)建請求,其事務(wù)體是CreateSessionTxn。

  (4) 注冊于激活會話。處理由非Leader服務(wù)器轉(zhuǎn)發(fā)過來的會話創(chuàng)建請求。

  4. 事務(wù)處理

  (1) 將請求交給ProposalRequestProcessor處理器。與提議相關(guān)的處理器,從ProposalRequestProcessor開始,請求的處理將會進(jìn)入三個子處理流程,分別是Sync流程、Proposal流程、Commit流程。

  Sync流程

  使用SyncRequestProcessor處理器記錄事務(wù)日志,針對每個事務(wù)請求,都會通過事務(wù)日志的形式將其記錄,完成日志記錄后,每個Follower都會向Leader發(fā)送ACK消息,表明自身完成了事務(wù)日志的記錄,以便Leader統(tǒng)計每個事務(wù)請求的投票情況。

  Proposal流程

  每個事務(wù)請求都需要集群中過半機(jī)器投票認(rèn)可才能被真正應(yīng)用到內(nèi)存數(shù)據(jù)庫中,這個投票與統(tǒng)計過程就是Proposal流程。

    · 發(fā)起投票。若當(dāng)前請求是事務(wù)請求,Leader會發(fā)起一輪事務(wù)投票,在發(fā)起事務(wù)投票之前,會檢查當(dāng)前服務(wù)端的ZXID是否可用。

    · 生成提議Proposal。若ZXID可用,Zookeeper會將已創(chuàng)建的請求頭和事務(wù)體以及ZXID和請求本身序列化到Proposal對象中,此Proposal對象就是一個提議。

    · 廣播提議。Leader以ZXID作為標(biāo)識,將該提議放入投票箱outstandingProposals中,同時將該提議廣播給所有Follower。

    · 收集投票。Follower接收到Leader提議后,進(jìn)入Sync流程進(jìn)行日志記錄,記錄完成后,發(fā)送ACK消息至Leader服務(wù)器,Leader根據(jù)這些ACK消息來統(tǒng)計每個提議的投票情況,當(dāng)一個提議獲得半數(shù)以上投票時,就認(rèn)為該提議通過,進(jìn)入Commit階段。

    · 將請求放入toBeApplied隊列中。

    · 廣播Commit消息。Leader向Follower和Observer發(fā)送COMMIT消息。向Observer發(fā)送INFORM消息,向Leader發(fā)送ZXID。

  Commit流程

    · 將請求交付CommitProcessor。CommitProcessor收到請求后,將其放入queuedRequests隊列中。

    · 處理queuedRequest隊列請求。CommitProcessor中單獨的線程處理queuedRequests隊列中的請求。

    · 標(biāo)記nextPending。若從queuedRequests中取出的是事務(wù)請求,則需要在集群中進(jìn)行投票處理,同時將nextPending標(biāo)記位當(dāng)前請求。

    · 等待Proposal投票。在進(jìn)行Commit流程的同時,Leader會生成Proposal并廣播給所有Follower服務(wù)器,此時,Commit流程等待,直到投票結(jié)束。

    · 投票通過。若提議獲得過半機(jī)器認(rèn)可,則進(jìn)入請求提交階段,該請求會被放入commitedRequests隊列中,同時喚醒Commit流程。

    · 提交請求。若commitedRequests隊列中存在可以提交的請求,那么Commit流程則開始提交請求,將請求放入toProcess隊列中,然后交付下一個請求處理器:FinalRequestProcessor。

  5. 事務(wù)應(yīng)用

  (1) 交付給FinalRequestProcessor處理器。FinalRequestProcessor處理器檢查outstandingChanges隊列中請求的有效性,若發(fā)現(xiàn)這些請求已經(jīng)落后于當(dāng)前正在處理的請求,那么直接從outstandingChanges隊列中移除。

  (2) 事務(wù)應(yīng)用。之前的請求處理僅僅將事務(wù)請求記錄到了事務(wù)日志中,而內(nèi)存數(shù)據(jù)庫中的狀態(tài)尚未改變,因此,需要將事務(wù)變更應(yīng)用到內(nèi)存數(shù)據(jù)庫。

  (3) 將事務(wù)請求放入隊列commitProposal。完成事務(wù)應(yīng)用后,則將該請求放入commitProposal隊列中,commitProposal用來保存最近被提交的事務(wù)請求,以便集群間機(jī)器進(jìn)行數(shù)據(jù)的快速同步。

  6. 會話響應(yīng)

  (1) 統(tǒng)計處理。Zookeeper計算請求在服務(wù)端處理所花費的時間,統(tǒng)計客戶端連接的基本信息,如lastZxid(最新的ZXID)、lastOp(最后一次和服務(wù)端的操作)、lastLatency(最后一次請求處理所花費的時間)等。

  (2) 創(chuàng)建響應(yīng)ConnectResponse。會話創(chuàng)建成功后的響應(yīng),包含了當(dāng)前客戶端和服務(wù)端之間的通信協(xié)議版本號、會話超時時間、sessionID和會話密碼。

  (3) 序列化ConnectResponse。

  (4) I/O層發(fā)送響應(yīng)給客戶端。

  2.2 SetData請求

  服務(wù)端對于SetData請求大致可以分為四步,預(yù)處理、事務(wù)處理、事務(wù)應(yīng)用、請求響應(yīng)。

  1. 預(yù)處理

  (1) I/O層接收來自客戶端的請求。

  (2) 判斷是否是客戶端"會話創(chuàng)建"請求。對于SetData請求,按照正常事務(wù)請求進(jìn)行處理。

  (3) 將請求交給PrepRequestProcessor處理器進(jìn)行處理。

  (4) 創(chuàng)建請求事務(wù)頭。

  (5) 會話檢查。檢查該會話是否有效。

  (6) 反序列化請求,并創(chuàng)建ChangeRecord記錄。反序列化并生成特定的SetDataRequest請求,請求中包含了數(shù)據(jù)節(jié)點路徑path、更新的內(nèi)容data和期望的數(shù)據(jù)節(jié)點版本version。同時根據(jù)請求對應(yīng)的path,Zookeeper生成一個ChangeRecord記錄,并放入outstandingChanges隊列中。

  (7) ACL檢查。檢查客戶端是否具有數(shù)據(jù)更新的權(quán)限。

  (8) 數(shù)據(jù)版本檢查。通過version屬性來實現(xiàn)樂觀鎖機(jī)制的寫入校驗。

  (9) 創(chuàng)建請求事務(wù)體SetDataTxn。

  (10) 保存事務(wù)操作到outstandingChanges隊列中。

  2. 事務(wù)處理

  對于事務(wù)請求,服務(wù)端都會發(fā)起事務(wù)處理流程。所有事務(wù)請求都是由ProposalRequestProcessor處理器處理,通過Sync、Proposal、Commit三個子流程相互協(xié)作完成。

  3. 事務(wù)應(yīng)用

  (1) 交付給FinalRequestProcessor處理器。

  (2) 事務(wù)應(yīng)用。將請求事務(wù)頭和事務(wù)體直接交給內(nèi)存數(shù)據(jù)庫ZKDatabase進(jìn)行事務(wù)應(yīng)用,同時返回ProcessTxnResult對象,包含了數(shù)據(jù)節(jié)點內(nèi)容更新后的stat。

  (3) 將事務(wù)請求放入commitProposal隊列。

  4. 請求響應(yīng)

  (1) 創(chuàng)建響應(yīng)體SetDataResponse。其包含了當(dāng)前數(shù)據(jù)節(jié)點的最新狀態(tài)stat。

  (2) 創(chuàng)建響應(yīng)頭。包含當(dāng)前響應(yīng)對應(yīng)的事務(wù)ZXID和請求處理是否成功的標(biāo)識。

  (3) 序列化響應(yīng)。

  (4) I/O層發(fā)送響應(yīng)給客戶端。

  2.3 GetData請求

  服務(wù)端對于GetData請求的處理,大致分為三步,預(yù)處理、非事務(wù)處理、請求響應(yīng)。

  1. 預(yù)處理

  (1) I/O層接收來自客戶端的請求。

  (2) 判斷是否是客戶端"會話創(chuàng)建"請求。

  (3) 將請求交給PrepRequestProcessor處理器進(jìn)行處理。

  (4) 會話檢查。

  2. 非事務(wù)處理

  (1) 反序列化GetDataRequest請求。

  (2) 獲取數(shù)據(jù)節(jié)點。

  (3) ACL檢查。

  (4) 獲取數(shù)據(jù)內(nèi)容和stat,注冊Watcher。

  3. 請求響應(yīng)

  (1) 創(chuàng)建響應(yīng)體GetDataResponse。響應(yīng)體包含當(dāng)前數(shù)據(jù)節(jié)點的內(nèi)容和狀態(tài)stat。

  (2) 創(chuàng)建響應(yīng)頭。

  (3) 統(tǒng)計處理。

  (4) 序列化響應(yīng)。

  (5) I/O層發(fā)送響應(yīng)給客戶端。

三、總結(jié)

  本篇博文講解了Zookeeper服務(wù)端對于客戶端不同請求的處理的具體流程,可能從文字上看步驟會顯得相對枯燥,但是會為之后的源碼分析打下很好的基礎(chǔ),謝謝各位園友的觀看~

總結(jié)

以上是生活随笔為你收集整理的【分布式】Zookeeper请求处理的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。