聊聊Zookeeper的會話(下篇)

2021-02-14 糖爸的架構師之路

寫在前面

小夥伴們大家好,距離上次更新已經有快一個月了。之所以一直沒更新,是因為整個十月份都比較忙。在忙什麼呢?沒錯!整個十月份所有的空閒時間,我都在打遊戲!!因為之前買了一些遊戲一直沒有打通,一直心心念,總感覺像吃飯吃了一半。所以十月份基本所有的空餘時間都在填之前的坑。戰神4,刺客信條:大革命/梟雄,看門狗、美末,基本所有的大作該打的都打完了。但是唯獨有一個,那就是 只狼!!!這個遊戲簡直變態,魂類遊戲的又一次巔峰,可玩性和難度都非常高。所以導致現在遊戲買了半年多,才打到蝴蝶!沒錯,就是第一個BOSS還沒過!太難了,真的太難了。感覺死的次數太多快要吧遊戲裡所有的人都染上龍咳在之前的文章聊聊Zookeeper的會話(上)和聊聊Zookeeper的會話(中篇)兩篇文章中,我們著重介紹了會話在Zookeeper客戶端側的創建和管理策略以及服務端側的管理策略。其中在中篇中,我們還結合會話的超時時間,詳細的介紹了一下Zookeeper在服務端側的會話管理機制。例如會話分桶、會話激活、會話超時檢查、會話清理等。在本章中,我們重點來說一下會話在Zookeeper是如何創建的。

ZooKeeper服務端對於會話創建的處理,大體可以分為請求接收、會話創建、預處理、事務處理、事務應用和會話響應6個部分。由於事務處理和事務應用這兩部分涉及到ZAB協議,內容較多。所以我們放到下一篇文章中去講解,本文我們重點關注請求接收、會話創建、預處理、會話響應這四部分內容

在 ZooKeeper中,NIOServerCnxn實例維護每一個客戶端連接,客戶端與服務端的所有通信都是由NIOServerCnxn負責的,其負責統一接收來自客戶端的所有請求,並將請求內容從底層網絡 I/O中完整地讀取出來。核心方法在NIOServerCnxn#doIO()方法中

NIOServerCnxn 在負責網絡通信的同時,自然也承擔了客戶端會話的載,每個會話都會對應一個NIOServerCnxn實體。因此,對於每個請求,ZooKeeper 都會檢查當前NIOServerCnxn 實體是否已經被初始化。如果尚未被初始化,那麼就可以確定該客戶端請求一定是"會話創建"請求。在會話創建初期,NIOServerCnxn尚未得到初始化,因此此時的第一個請求必定是"會話創建"請求。具體代碼如下:

initialized是一個布爾變量,默認為false,當第一次初始化完成後會變為true,保證不會重複執行會話創建請求。

一旦確定當前客戶端請求是"會話創建"請求,那麼服務端就可以對其進行反序列化,並生成一個ConnectRequest 請求實體。具體代碼在ZooKeeperServer#processConnect方法中。

在ZooKeeper的設計實現中,如果當前ZooKeeper伺服器是以ReadOnly模式啟動的,那麼所有來自非 ReadOnly 型客戶端的請求將無法被處理。因此,針對ConnectRequest,服務端會首先檢查其是否是 ReadOnly 客戶端,並以此來決定是否接受該會話創建請求。具體代碼同樣在ZooKeeperServer#processConnect方法中:

在正常情況下,同一個ZooKeeper集群中,服務端的zxid必定大於客戶端的zxid,因此如果發現客戶端的 zxid值大於服務端的Zxid值,那麼服務端將不接受該客戶端的會話創建請求。zxid是Zookeeper的事務標識id,當Leader產生了⼀個事務,就會為該事務分配⼀個標識符,我們稱之為Zookeeper事務ID。通過Zxid對事務進⾏標識,就可以按照Leader所指定的順序在各個伺服器中按序執⾏。伺服器之間在進行新的Leader選舉時也會交換zxid信息,這樣就可以知道哪個⽆故障伺服器接收了更多的事務,並可以同步他們之間的狀態信息。具體代碼同樣在ZooKeeperServer#processConnect方法中:


客戶端在構造ZooKeeper實例的時候,會有一個 sessionTimeout 參數用於指定會話的超時時間。客戶端向伺服器發送這個超時時間後,伺服器會根據自己的超時時間限制最終確定該會話的超時時間,這個過程就是sessionTimeout協商過程。具體代碼同樣在processConnect方法中:

關於超時這裡我還想再多說一下。ZooKeeper的超時異常包括兩種:

ZooKeeper客戶端的readTimeout無法設置,它的值是根據會話超時時間計算出來的。計算規則為:

當客戶端還未完成連接(即服務端還未完成客戶端會話的創建,未通知客戶端)之前,此時readTimeout為客戶端設置的sessionTimeout * 2 / 3

當客戶端完成連接後,readTimeout為客戶端和服務端協商後sessionTimeout * 2 / 3。協商後的sessionTimeout取值取決於服務端配置的minSessionTimeout和maxSessionTimeout,默認情況下,ZooKeeper服務端對超時時間的限制介於2個 tickTime到20個tickTime之間。即如果我們設置 tickTime值為2000毫秒的話,那麼服務端就會限制客戶端的超時時間,使之介於4秒到40秒之間。如果連接斷開,重連後客戶端使用的sessionTimeout依然使用協商後的sessionTimeout,也就是,通過構造器傳入的sessionTimeout只在建立連接之前使用。

當發生連接丟失時:

客戶端的請求操作將拋出異常

org.apache.zookeeper.KeeperException.ConnectionLossException

     2. 客戶端註冊的Watcher也將收到通知Watcher.Event.KeeperState.Disconnected

但是,這種時候一般還未發生會話超時,ZooKeeper客戶端在下次執行請求操作的時候,會先執行自動重連,重新連接成功後,再執行操作請求。因此下一次操作請求一般情況下並不會出現問題。服務端會話超時SessionTimeout導致的客戶端連接失效
客戶端的會話超時時間sessionTimeout由客戶端和服務端協商決定。 服務端會通過分桶算法管理Session的失效操作,這個我們在中篇中也詳細的說過,不明白的小夥伴可以回去翻看一下。這種情況下,客戶端需要主動重新創建連接(即重新創建ZooKeeper實例對象),然後使用新的連接重試操作。

        當客戶端連接丟失時,客戶端首先觸發了連接丟失的異常(該異常在會話超時異常之前被檢測到,因為連接丟失異常是客戶端主動檢測的,而會話超時需要等到客戶端下一次操作時,服務端檢測到會話超時才會通知客戶端)

服務端根據客戶端請求中是否包含sessionID來判斷該客戶端是否需要重新創建會話。如果客戶端請求中已經包含了sessionID,那麼就認為該客戶端正在進行會話重連。在這種情況下,服務端只需要重新打開這個會話,否則需要重新創建。具體代碼同樣在processConnect方法中:

至此,請求接收階段的流程已經走完,如果會話需要創建,則進入會話創建階段

會話創建

在為客戶端創建會話之前,服務端首先會為每個客戶端都分配一個sessionID。分配方式其實很簡單,每個ZooKeeper伺服器在啟動的時候,都會初始化一個會話管理器(SessionTracker),同時初始化 sessionID,這個在上一篇文章中已經介紹過,這裡就不再贅述了。

創建會話最重要的工作就是向SessionTracker中註冊會話。SesionTracker 中維護了兩個比較重要的數據結構,分別是 sessionswithTimeout和sessionsById。前者根據sessionID保存了所有會話的超時時間,而後者則是根據sessiolID保存了所有會話實體。在會話創建初期,就應該將該客戶端會話的相關信息保存到這兩個數據結構中,方便後續會話管理器進行管理。

向SessionTracker註冊完會話後,接下來還需要對會話進行激活操作。激活會話過程涉及ZooKeeper會話管理的分桶策略,這個在上一篇文章中中已經詳細介紹過,這裡也不再贅述。

下面是保存sessionsWithTimeout集合的方法

ZooKeeper 對於每個客戶端請求的處理模型採用了典型的責任鏈模式,每個客戶端請求都會由幾個不同的請求處理器依次進行處理。另外,在提交給第一個請求處理器前,ZooKeeper 還會根據該請求所屬的會話,進行一次激活會話操作,以確保當前會話處於激活狀態。完成會話激活之後,ZooKeeper就會將請求提交給第一個請求處理器∶PrepRequestProcessor。具體代碼如下:

PropRequestProcessor#run()方法中取出Request對象

對於事務請求,ZooKeeper 首先會為其創建請求事務頭。請求事務頭是每一個Zookeeper事務請求中非常重要的一部分,服務端後續的請求處理器都是基於該請求頭來識別當前請求是否是事務請求。請求事務頭包含了一個事務請求最基本的一些信息,包括sessionID、zxid、cxid和請求類型等,具體結構如下圖所示屬性
說明clientId
客戶端ID,用來唯一標識該請求所述的客戶端
cxid
客戶端的操作序列號zxid
該事物請求對應的事務id
time
伺服器開始處理該事務請求的時間
type
事務請求的類型,例如create,delete,setData等

對於事務請求,ZooKeeper還會為其創建請求的事務體。在此處由於是"會話創建"請求,因此會創建事務體CreateSessionTxn。此處的註冊與激活會話過程,和上面提到的過程是一致的,雖然重複了,但是不會引起額外的問題。此處進行會話註冊與激活的目的是處理由非 Leader 伺服器轉發過來的會話創建請求。在這種情況下,其實尚未在Leader的SessionTracker中進行會話的註冊,因此需要在此處進行一次註冊與激活。

至此,預處理的流程結束,後面便是和zab協議相關的同步流程、Proposal流程、commit流程以及事務應用流程。這些內容我們放到下一篇來介紹。

最後,客戶端請求在經過ZooKeeper服務端處理鏈路的所有請求處理器的處理後,就進入最後的會話響應階段了。會話響應階段非常簡單,大體分為以下4個步驟。

至此,客戶端的"會話創建"請求已經從ZooKeeper 請求處理鏈路上的所有請求處理器間完成了流轉。到這一步,ZooKeeper會計算請求在服務端處理所花費的時間,同時還會統計客戶端連接的一些基本信息,包括lastZxid(最新的ZXID)、lastOp(最後一次和服務端的操作)和lastLatency(最後一次請求處理所花費的時間)等。ConnectResponse 就是一個會話創建成功後的響應,包含了當前客戶端與服務端之間的通信協議版本號protocolVersion、會話超時時間、sessionID和會話密碼。

序列化 ConnctResponse。

I/O層發送響應給客戶端。

以上便是服務端創建會話的整個流程,其中關於ZAB協議相關的內容將放在下一篇文章中介紹,敬請期待吧~~ 

相關焦點

  • ZooKeeper基本原理你懂了麼?
    最終一致性:client不論連接到哪個Server,展示給它都是同一個視圖,這是zookeeper最重要的性能。2. 可靠性:具有簡單、健壯、良好的性能,如果消息m被到一臺伺服器接受,那麼它將被所有的伺服器接受。3. 實時性:Zookeeper保證客戶端將在一個時間間隔範圍內獲得伺服器的更新信息,或者伺服器失效的信息。
  • ZooKeeper——大數據平臺之分布式應用程式協調服務教程
    在安裝目錄下創建數據文件夾:zkdatadataDir=/opt/module/zookeeper-3.4.5/zkdata3) 設置本機id:生成myid文件,在文件中寫入本機序號(server.x中的x,僅有一行)。
  • QQ隱藏會話在哪怎麼找出來 恢復顯示qq隱藏會話方法
    QQ隱藏會話在哪怎麼找出來?把不想接收的會話隱藏了但是有時候又需要或者後悔了怎麼辦,小編整理了QQ隱藏會話怎麼恢復的步驟供大家參考。  恢復顯示qq隱藏會話方法  1、點擊打開手機的qq,點擊左上角的圖標。
  • Twitter會話定位攻略看這一篇就夠了!
    藉助Twitter會話定位功能,企業可以根據他們在平臺上積極參與的對話來快速定位目標受眾。從25個類別的10000多個對話主題中選擇Twitter會話定位,包括體育,生活方式,視頻遊戲,書籍等等。 一、Twitter會話定位怎麼運作?
  • 騰訊企點客服如何使用員工會話分析?
    在【員工會話分析】中,可以查看消息記錄、會話客戶數等信息,方便企業了解會話具體內容及有效會話數。可一鍵導出包含滿意度在內的全員接待詳情數據,同時報表增加「客戶ID」數據,為企業的會話質量監控及低滿意度客戶回訪提供數據支持。
  • 企業微信會話內容存檔功能全規則整理
    企業微信會話內容存檔是企業微信自帶的一個接口能力,它支持將企業成員的內部、外部客戶服務溝通內容存檔保存,並且企業可設置需要存檔的成員範圍。企業管理員只需登錄企業微信管理後臺,在管理工具欄目中即可看到會話內容存檔的功能入口。
  • 企業微信會話存檔,史上最全功能講解!
    概念闡述 對接企業微信的會話內容存檔接口,為企業提供數據解析,和結構化呈現服務,實現企業對員工聊天記錄的可查,可控。有效防止 , 監管員工不合規或有違企業利益的操作。
  • 微信7.0.16iOS測試版新增隱藏會話功能:不會刪除聊天記錄
    在使用微信時,因為各種各種的原因,你可能不想見到與某個人的聊天會話一直出現在列表裡,或者不想其他人看到,但是又不得不面對它時刻就在那裡的煩惱。因為一旦將其從聊天會話列表中刪除,該聊天的所有消息記錄也會被清空且無法恢復。這個問題可能很快就可以解決了。
  • 微信7.0.16 for iOS測試版新增隱藏會話功能:不會刪除聊天記錄
    在使用微信時,因為各種各種的原因,你可能不想見到與某個人的聊天會話一直出現在列表裡,或者不想其他人看到,但是又不得不面對它時刻就在那裡的煩惱。因為一旦將其從聊天會話列表中刪除,該聊天的所有消息記錄也會被清空且無法恢復。
  • 《水手英語聽力與會話》必對題已標註完成-海員考證寶典
    前言:海員考證寶典已對水手英語聽力與會話--【必對題】完成標註。溫馨提示:已開通的請在複習第二遍再題庫重新!不要扎堆下載造成卡頓。下載務必等到100%並自動跳轉為止,避免下載不完整造成沒有聲音和圖片!水手聽力與會話-必對題必對題是擺在遠洋水手的船員考試中攔路虎!
  • 教你學日語會話課程,大家都愛的甜食用日語如何表達
    教你學日語會話課程,大家都愛的甜食用日語如何表達 2020-11-24 16:46
  • RubyMine 2020.1 發布:新的 LightEdit 模式以及可拆分的終端會話
    終端現在可以垂直或水平拆分終端會話,以並排運行它們。從終端調用上下文菜單就可以創建、導航或關閉拆分終端會話。
  • 【學上海話】情景會話——紅嘴綠鸚哥('anggu〈名〉鸚鵡) 作者:白米 朗讀:田以光
    【學上海話】情景會話【學上海話】情景會話——借書作者:張林龍滬語誦讀:宗克鳴趙群社 2019-12-15【學上海話】情景會話——學學上海言話作者:白米滬語誦讀:田以光2019-12-14【學上海話】情景會話——種植花草作者:張林龍滬語誦讀:薛南平陳美蓮 2019-12-11【學上海話】情景會話——湯圓店裡(松江話)作者:白米播音:田以光2019-12-03【學上海話】情景會話——一個獨行客作者:白米播音:田以光陳芳原創:學上海閒話2019-11-29【學上海話】情景會話——買碎肉作者:張林龍播音:田以光管平 2019-11-28
  • 9點1氪:新版微信可隱藏聊天會話不刪聊天記錄;董明珠再談舉報...
    來源:36氪微信發布 iOS 7.0.16 測試版:微信新增會話不顯示選項,微信可隱藏聊天會話不刪聊天記錄。文| 耿吳菁整理 | 穆宇汀 崔永旺點擊上方「36氪隨聲聽」,一鍵收聽大公司熱門新聞。微信發布 iOS 7.0.16 測試版:微信新增會話不顯示選項,微信可隱藏聊天會話不刪聊天記錄近日,微信發布 iOS 7.0.16 測試版。新版增加聊天框 「不顯示」選項,可以在不刪除對方聊天記錄的基礎上,讓其對話框在列表中消除。
  • 韓語學習:如何高效學習延世韓國語教材,韓語語法會話講解二
    韓語學習:如何高效學習延世韓國語教材,韓語語法會話講解二
  • 藝術家系列NO.1217-Csyday 韓國插畫師 相當精緻的人物立繪 下篇
    藝術家系列NO.1217-Csyday 韓國插畫師 相當精緻的人物立繪 下篇藝術家系列NO.1217-Csyday 韓國插畫師 相當精緻的人物立繪 下篇藝術家系列NO.1217-Csyday 韓國插畫師 相當精緻的人物立繪 下篇藝術家系列NO.1217
  • 藝術家系列NO.1255-Hane Ru 日本插畫師 女孩永遠是最美的 下篇
    藝術家系列NO.1255-Hane Ru 日本插畫師 女孩永遠是最美的 下篇藝術家系列NO.1255-Hane Ru 日本插畫師 女孩永遠是最美的 下篇藝術家系列NO.1255-Hane Ru 日本插畫師 女孩永遠是最美的 下篇藝術家系列NO.1255
  • 藝術家系列NO.1337-Syokumura 日本插畫師 唯美的頹廢系插畫 下篇
    藝術家系列NO.1337-Syokumura 日本插畫師 唯美的頹廢系插畫 下篇藝術家系列NO.1337-Syokumura 日本插畫師 唯美的頹廢系插畫 下篇藝術家系列NO.1337-Syokumura 日本插畫師 唯美的頹廢系插畫 下篇藝術家系列NO
  • 微信更新 iOS版上線青少年模式與會話不顯示
    你可以在微信頁面中選擇想隱藏的聊天會話,向左滑動新增了【不顯示】操作。點擊後,該會話將從首頁隱藏,但不會刪除聊天記錄,而有新消息時會重新顯示。也就是說能刪掉對話框但是不刪聊天記錄 ,實際上QQ很早之前就可以刪除對話框保留聊天記錄,很多網友對這個功能期盼已久,隱藏後的界面太清爽了,但升級後也有一些網友反饋沒有批量處理功能,隱藏多個群很費時間。
  • 藝術家系列NO.1253-1096811 日本插畫師 超治癒的動物系美食 下篇
    藝術家系列NO.1253-1096811 日本插畫師 超治癒的動物系美食 下篇藝術家系列NO.1253-1096811 日本插畫師 超治癒的動物系美食 下篇藝術家系列NO.1253-1096811 日本插畫師 超治癒的動物系美食 下篇藝術家系列NO.1253