揭祕井井有條的流水線(ZooKeeper 原理篇)

削微寒發表於2021-02-10

本文作者:HelloGitHub-老荀

Hi,這裡是 HelloGitHub 推出的 HelloZooKeeper 系列,免費開源、有趣、入門級的 ZooKeeper 教程,面向有程式設計基礎的新手。

ZooKeeper 是 Apache 軟體基金會的一個軟體專案,它為大型分散式計算提供開源的分散式配置服務、同步服務和命名註冊。 ZooKeeper 曾經是 Hadoop 的一個子專案,但現在是一個頂級獨立的開源專案。

本系列教程是從零開始講解 ZooKeeper,內容從最基礎的安裝使用到背後原理和原始碼的講解,整個系列希望通過有趣文字、詼諧的氣氛中讓 ZK 的知識“鑽”進你聰明的大腦。本教程是開放式:開源、協作,所以不管你是新手還是老司機,我們都希望你可以加入到本教程的貢獻中,一起讓這個教程變得更好

  • 新手:參與修改文中的錯字、病句、拼寫、排版等問題
  • 使用者:參與到內容的討論和問題解答、幫助其他人的事情
  • 老司機:參與到文章的編寫中,讓你的名字出現在作者一欄

專案地址:https://github.com/HelloGitHub-Team/HelloZooKeeper

從今天這篇開始,開始進入 ZK 的原理講解了,我會盡量把背後的原理比喻的有趣點的,大家放心看下去吧~

一、辦事處的新同事

老規矩~我們繼續來看看動物村又發生了什麼事情吧?

1.1 馬果果要做老闆啦

馬果果畢竟年紀大了,每天接待這麼多村民,實在是吃不消了,最終決定向村委會申請下能不能多招幾個人,讓他也能過過當老闆的癮。村委會考慮再三最終還是同意了,並且決定由馬果果自己去鄰里街坊找合適的人拉來工作。馬果果一直非常注重體育鍛煉,所以三天兩頭泡在健身房裡,於是開始在健身房裡物色人選,最終選了三個身強體壯的年輕小夥,並且連暱稱都給他們起好了,一個 80 多公斤叫小P,一個 90 多公斤叫小S,最後一個 200 斤叫小F

招人完成後,把辦公室的佈置也換下,變成了這樣:

馬果果現在高枕無憂在後方當管理者了,前面的工作都交接給了三個小夥,三個小夥各自工作也比較簡單,我們一個個來看吧

1.2 細心的小P

作為辦事處第一個被村民接觸到的員工,小P先會對要來處理事務的村民進行檢查並做一些簡單的詢問:

這裡必須得提下,如果出現了異常錯誤,小P不會終止對該村民的服務,也會繼續引導他至小S的櫃檯繼續辦理

1.3 認真的小S

小S的工作也非常簡單,我們直接來看下流程圖:

小S是辦事處的記錄員,一直手邊備著一本備忘錄:

這本備忘錄不需要去管是誰來登記的只需要把登記具體的內容(甚至是小P標記的異常)給記錄下來就行,之後每過一段時間統一進行歸檔。

1.4 能幹的小F

小F作為曾經的大力士和馬果果是有切磋過的,並且以微弱的優勢輸給了馬果果,但是大度的小F並沒有把這些陳年舊事放在心中,仍然心甘情願的來馬果果手下幫忙,真是一位受人尊敬的好同志啊!

小S這邊每次歸檔完就會把那些事務一起交給小F,而作為辦事處坐在最後一位的業務員,小F手中握有馬果果交給他的兩個核心檔案:小紅本和小黃本!

需要把村民的請求認認真真的記錄在小紅本上,同時還需要檢視是否有需要通知的村民在小黃本上,代替馬果果對他們進行電話通知。

看起來小F做的事很少,但是實際是最多的,只是我這裡把小紅本和小黃本的邏輯給簡單化了,小紅本和小黃本我之後單獨開篇講解,這樣又能水一期。


二、井井有條的背後

小故事講完了,下面用猿話進行翻譯:

我起名的時候為了加深大家的印象才用了這三個名字:

  • 小P對應程式碼中的 PrepRequestProcessor
  • 小S對應程式碼中的 SyncRequestProcessor
  • 小F對應程式碼中的 FinalRequestProcessor

在服務端啟動的時候,就會把這三個處理器按照 P -> S -> F 的順序串成一個鏈條,並且 P 和 S 本身就是一個執行緒物件,兩者會隨著服務端的啟動而啟動。

而 P 和 S 啟動後各自都會使用一個死迴圈來處理主要的邏輯,而這部分 ZK 又會使用一個非常經典的模式來處理:生產者和消費者模式!他們各自都維護了一個阻塞佇列,將接收請求和處理請求的邏輯拆開,從這個設計上就提升了吞吐量和效能。

其實不光光是這裡,在 ZK 中這個模式可謂是隨處可見,之後有遇到的時候會再說,我們現在把三個處理器的處理邏輯再深挖一下。

2.1 PrepRequestProcessor

從流程上可以看到,PrepRequestProcessor 不涉及記憶體的操作和檔案的操作,作為第一個處理器主要負責做些校驗和標記的任務。

2.2 SyncRequestProcessor

這裡需要額外的提一下,流程中的兩個粉紅色的框,分別對是否快照和是否歸檔進行了判斷:

  • 是否快照:事務記錄的數量或者大小大於了某一個程度,而這個程度的數字則是一個隨機數(每次快照完都會重置)
  • 是否歸檔:上次歸檔的時間和當前時間是否超過了配置的間隔時間(預設該配置為 0),或者事務的記錄超過了配置的數量(預設為 1000)

使用了這兩個判斷控制了快照和歸檔的頻率:

  • 頻率低的話,一次寫入更多資料到磁碟,效能更好,但是容災能力就低
  • 頻率高的話,對效能會有一定影響,但是容災能力強

2.3 FinalRequestProcessor

好像這張圖和上面那張圖其實沒什麼區別(Orz),就是因為細節都在小紅本和小黃本中,所以留到下一章展開。

為什麼小P那邊的異常不直接返回給客戶端,而要向後傳遞至小F再響應?我想可能是為了能統一每個處理器的職責,客戶端的響應都是小F來處理的。

在這裡我小小的劇透下,以上的場景實際是 ZK 單機版的處理場景,如果換成了叢集版會在該鏈條中加入更多的處理器,之後會涉及到叢集后再講。

三、總結

本章節介紹了單機版的 ZK 處理客戶端請求的流程,並且通過責任鏈的方式把不同的邏輯拆分到不同的物件中去處理。下一章我們會正式進入記憶體模型和通知機制的實現,一起來看看馬果果手中的兩大核心賬本到底是怎麼記錄的吧~

由於本章開始進入了 ZK 的原理講解,一篇文章以及我個人很難做到面面俱到,所以如果你有任何對文章中的疑問也可以是建議或者是對 ZK 原理部分的疑問,可以來我建立的話題中來討論,方便記錄和答疑:

地址:https://www.yuque.com/kaixin1002/yla8hz

我會為每一篇文章建立一個話題,這樣你就可以在其中討論,把你的問題困惑描述清楚。


關注 HelloGitHub 公眾號 收到第一時間的更新。

還有更多開源專案的介紹和寶藏專案等待你的發掘。

相關文章