一文看懂 ZooKeeper ,面試再也不用背八股(文末送PDF)

来源:https://www.cnblogs.com/datadance/archive/2022/05/20/16293445.html
-Advertisement-
Play Games

ZooKeeper知識點總結 一、ZooKeeper 的工作機制 二、ZooKeeper 中的 ZAB 協議 三、數據模型與監聽器 四、ZooKeeper 的選舉機制和流程 本文將以如下內容為主線講解ZooKeeper中的學習重點,包括 ZooKeeper 中的角色、ZAB協議、數據模型、選舉機制、 ...


ZooKeeper知識點總結

 

本文將以如下內容為主線講解ZooKeeper中的學習重點,包括 ZooKeeper 中的角色、ZAB協議、數據模型、選舉機制、監聽器原理以及應用場景等。會對相關的面試題或開發中常見內容,進行重點講解。
在這裡插入圖片描述
接下來將帶領大家入門學習 ZooKeeper 系列的內容,力求通俗易懂,圖文並茂。

一、ZooKeeper 的工作機制

1. 什麼是ZooKeeper

ZooKeeper 是一個分散式協調服務,其設計的初衷是為分散式軟體提供一致性服務。其本質上,就是文件系統+通知機制。

ZooKeeper 提供了一個類似 Linux 文件系統的樹形結構,ZooKeeper 的每個節點既可以是目錄也可以是數據,並且 ZooKeeper 還提供了對每個節點的監控與通知機制。

2. ZooKeeper 的工作機制

ZooKeeper 採用的是主從模式,有主節點和從節點。從設計模式的角度,它是一個基於觀察者模式設計的分散式服務管理框架,負責存儲和管理大家都關心的數據,然後接受觀察者的註冊,一旦這些數據的狀態發生變化,ZooKeeper 就將負責通知已經註冊的那些觀察者做出相應的反應。

3. ZooKeeper 的角色及其關係

ZooKeeper 中的角色包括 Leader、Follower、Observer。Leader 是集群主節點,主要負責管理集群狀態和接收用戶的寫請求;Follower 是從節點,主要負責集群選舉投票和接收用戶的讀請求;Observer 的功能與 Follower 類似,只是沒有投票權,主要用於分擔 Follower 的讀請求,降低集群的負載。
在這裡插入圖片描述

a. Leader

一個運行中的 Zookeeper 集群只有一個 Leader 服務,Leader 服務主要包括以下兩個指責:

  • 負責集群數據的寫操作。所有寫操作必須要 Leader 完成之後,才可以將寫操作廣播到其他 Follower,並且只有超過半數節點(不包括 Observer)寫入成功後,這些寫請求才算寫成功;
  • 發起並維護各個 Follower 以及 Observer 之間的心跳,以監控集群的運行狀態。

b. Follower
一個 Zookeeper 集群可以有多個 Follower,Follower通過心跳與 Leader 保持連接。Follower 服務主要有以下兩個指責:

  • 負責集群數據的讀操作。Follower 在接受到一個客戶端請求之後,會先判斷該請求是讀請求還是寫請求,若為讀請求,則 Follower 從本地節點上讀取數據並返回給客戶端;若為寫請求,則 Follower 會將寫請求轉發給 Leader 來處理。
  • 參與集群中 Leader 的選舉。當 Leader 失效之後,Follower 需要在集群選舉時進行投票;(後續會詳細講解選舉機制)

c. Observer

一個 Zookeeper 集群可以有多個 Observer,Observer 的主要職責是負責集群數據的讀操作,其功能同以上介紹的 Follower 的功能類似,主要的差別就是 Observer 沒有投票權。

4. 面試題:Follower 已經具備了 Observer 的所有功能,為什麼還要設計 Observer 角色 ?

這是因為 ZooKeeper 集群在運行過程中要支持更多的客戶端併發的操作,就需要增加更多的服務實例,而過多的服務實例會使得集群的投票階段變得複雜,選舉時間過長不利於集群故障的快速恢復。
因此,ZooKeeper 引入了 Observer 角色,Observer 不參與投票,只負責接收客戶端來的讀請求,以及將寫請求轉發給 Leader 。加入更多的 Observer 節點,不僅提高了 ZooKeeper 集群的吞吐量,保障了系統的穩定性。


二、ZooKeeper 中的 ZAB 協議

前面介紹了 ZooKeeper 的基本概念、角色、工作機制等內容,為了後續更好地學習 ZooKeeper 的原理,本節先給大家介紹一種分散式一致性協議——ZAB(ZooKeeper Atomic Broadcast,ZooKeeper 原子消息廣播協議)。

1. 什麼是ZAB

在介紹 ZAB 之前,先給大家介紹下 ZooKeeper 的由來。

ZooKeeper 最早起源於雅虎研究院的一個研究小組,當時雅虎內部很多大型系統都需要依賴一個類似的系統來進行分散式協調,為了讓把精力集中在業務邏輯上,雅虎研發人員開發了一個通用的解決了單點問題的分散式協調框架。

ZooKeeper 名字的由來:
立項之初,考慮到很多項目都是使用動物的名字來命名的,雅虎的工程師希望給這個項目也取一個動物的名字。有人開玩笑地說:“在這樣下去,我們這兒就變成動物園了!”此話一齣,大家紛紛表示就叫動物園管理員吧。

而 ZAB 協議最初也只是為雅虎內部那些高吞吐量、低延遲的分散式系統場景設計的,它並不是一種通用的分散式一致性演算法,而是專門為 ZooKeeper 設計的一種支持崩潰恢復的原子廣播協議,實現了一種主備模式的系統架構來保持集群中各副本之間數據的一致性。

2. 兩個概念

1)當前集群的周期號:Epoch

集群中每次 Leader 的重新選舉都會產生一個新的周期號(也有叫年代號的,都一個意思),周期號的產生規則則是在上一個周期號上加1,這樣當之前的 Leader 奔潰恢復後會發現自己的周期號比當前的周期號小,說明此時集群已經產生了一個新的 Leader,舊的 Leader 會再次以 Follower 的角色加入集群。

2)ZAB 協議的事務編號:Zxid

Zxid 是一個64位的數字,其中低32位存儲的是一個簡單的單調遞增的計數器,針對客戶端的每個事務請求,計數器都會加1。高32位存儲的是 Leader 的周期號 Epoch。每次選舉產生一個新的 Leader 時,該 Leader 就會從當前伺服器的日誌中取最大事務的 Zxid,獲取其中高32位的 Epoch 值並加1,以此作為一個新的 Epoch,並會將低32位從0開始重新計數。

3. 兩種模式

1)集群選主:恢復模式

當集群 Leader 出現崩潰,或者由於網路原因導致 Leader 和過半的 Follower 失去聯繫,那麼集群將開始選主,該過程為恢復模式。

Leader 的選舉機制不僅可以讓 Leader 節點知道自身被選舉為 Leader,同時還能需要讓集群中其他節點也能快速感知到選舉的新的 Leader 節點。

2)數據同步:廣播模式

當 Leader 被選舉出來後,Leader 將最新的集群狀態廣播給其他 Follower,該過程為廣播模式。在半數以上的 Follower 完成與 Leader 的狀態同步後,廣播模式結束。

4. ZAB 的實現過程

1)選舉階段

選舉階段的目的就是產生一個準 Leader,節點在一開始都處於選舉階段,只要有一個節點得到超過半數節點的票數,那麼它就可以當選準Leader,只有到達第三階段(同步階段)這個準Leader才會成為真正的Leader。
在這裡插入圖片描述

2)發現階段

在該階段中 Follower 和上一階段選舉出的準 Leader 進行通信,同步 Follower 最近接收的事務提議。這一階段的目的是發現當前大多數節點接收的最新提議,並且準 Leader 生成新 的epoch,然後讓 Follower 接收,更新它們的acceptedEpoch。
在這裡插入圖片描述

如果節點1認為節點L是 Leader,那麼當節點1嘗試連接節點L時,如果連接遭到拒絕,則集群將會重新進入選舉階段。

3)同步階段

同步階段主要是將 Leader 在前一階段獲得的最新提議信息同步到集群中所有的副本。並且只有當超過半數的節點都同步完成後,準 Leader 才會成為真正的 Leader 。Follower 只會接收 Zxid比自己 lastZxid 大的提議。
在這裡插入圖片描述
同步完成之後,集群的選主操作才算完成,新的 Leader 將產生。

4)廣播階段

在該階段,ZooKeeper 集群正式對外提供事務服務,這時 Leader 進行消息廣播,將其上的狀態通知到其他 Follower。若後續有新的節點加入進來,則 Leader 會對新節點進行狀態同步。


三、數據模型與監聽器

ZooKeeper 可用於統一命名服務、配置管理、集群管理、分散式通知協調、分散式鎖等場景,在這些應用場景中, ZooKeeper 內部是如何做到分散式數據一致性的呢?本節將給大家介紹下 ZooKeeper 內部是如何做到分散式數據一致性的。

ZooKeeper 使用了一個樹形結構的命名空間來表示其數據結構,其視圖結構和標準的 Unix 文件系統非常類似,但沒有引入傳統文件系統中目錄和文件等相關概念,而是將 ZooKeeper 樹中的每一個節點都稱之為一個 Znode。其數據結構如下圖所示。

在這裡插入圖片描述
類似文件系統的目錄樹,ZooKeeper 樹中的每個節點都可以擁有子節點,而不同的是,每個 Znode 節點都存儲了數據信息,同時也提供了對節點信息的監控等操作。

1. Znode 的數據模型

Znode 是 ZooKeeper 中數據的最小單元,每個 Znode 都兼具文件和目錄兩種特點,既能像文件一樣保存和維護數據,又可以由一系列使用斜杠(/)進行分割的方式作為路徑標識的一部分。每個 Znode 都有以下三部分組成。

  • Stat:狀態信息,用於存儲該 Znode 的版本、許可權、時間戳等信息;
  • Data:實際存儲的數據;
  • Children:對子節點的信息描述;

需要特別說明的是,Znode 節點雖然可以存儲數據信息,但它並不能像資料庫那樣存儲大量的數據,Znode 的設計初衷就是存儲分散式應用中的配置文件、集群狀態等元數據信息。

2. Znode 的控制訪問

1)ACL

ACL(Access Control List) 為訪問控制列表,應用程式會根據實際需求將用戶分為只讀、只寫以及讀寫用戶,每一個 Znode 節點都會有一個 ACL 用來約束不同的用戶對節點的訪問許可權。

2)原子操作

每一個 Znode 節點上都具有原子操作的特性,讀操作將獲取與節點相關的數據,寫操作將替換節點上的數據,上期文章中講到 ZooKeeper 都會為每一個事務請求分配一個全局唯一的事務編號 Zxid,每一個 Zxid 就對應一次更新操作,並可以通過 Zxid 來識別出更新操作請求的全局順序。

3. Znode 的節點類型

ZooKeeper 中的節點有兩種,分別為臨時節點和永久節點。節點的類型在創建時即被確定,並且不能改變。

1)臨時節點

臨時節點常被應用於心跳監控,舉個慄子,設置過期時間為 30s,要求各個子節點對應的服務端每 5s 發送一次心跳到 ZooKeeper 集群,當服務端連續 30s 沒有向 ZooKeeper 彙報心跳信息,也就是連續6次沒有收到心跳信息,就認為該節點宕機了,並將其從服務列表中移除。

臨時節點的生命周期依賴於創建它們的會話(Session)。一旦會話結束,臨時節點將被自動刪除,當然可以也可以手動刪除。

另外,ZooKeeper 的臨時節點不允許擁有子節點。

2)永久節點

永久節點的數據會一直存儲著,直到用戶調用介面將其數據刪除,該節點一般用於存儲一些永久性的配置信息。

4. Znode 的監聽器機制( 面試重點

ZooKeeper 的每個節點上都有一個 Watcher 用於監控節點數據的變化,當節點狀態發生改變時(Znode 新增、刪除、修改)將會觸發 Wahcher 所對應的操作。在 Watcher 被觸發時,ZooKeeper 會向監控該節點的客戶端發送一條通知說明節點的變化情況。
在這裡插入圖片描述
具體實現流程就是,客戶端向 ZooKeeper 伺服器註冊 Watcher 的同時,會將 Watcher 對象存儲在客戶端的 WatchManager 中。當 ZooKeeper 伺服器端觸發 Watcher 事件後,會向客戶端發送通知,客戶端線程從 WatchManager 中取出對應的 Watcher 對象來執行回調邏輯。


四、ZooKeeper 的選舉機制和流程

我們在本系列的第一期就介紹了 ZooKeeper 集群中的三個伺服器角色:Leader、Follower 和 Observer。其中,Leader 選舉是 ZooKeeper 中最重要的技術之一,也是保證分散式數據一致性的關鍵所在。本期內容將重點講解 Leader 是如何被選舉的。

1. 選舉機制概述

Zookeeper 在配置文件中並沒有指定 Master 和 Slave。但是,Zookeeper 工作時, 是有一個節點為 Leader,其他則為 Follower,而這個 Leader 是通過內部的選舉機制臨時產生的。

每個 Server 首先都提議自己是 Leader,併為自己投票,然後將投票結果與其他 Server 的選票進行對比,權重大的勝出,使用權重較大的選票更新自身的投票箱,我們介紹下伺服器啟動時期的 Leader 選舉。

1)每一個 Server 都會發出一個投票

在集群初次啟動時,每個 Server 都會推薦自己為 Leader,然後各自將這個投票發給集群中其他 Server。

2)接收來自各個 Server 的投票

每個 Server 在接收到其他 Server 的投票後,首先會判斷該票的有效性,包括檢查是否本輪投票,是否來自 Looking 狀態的 Server。(Looking 狀態表示當前集群正處於選舉狀態)

3)處理投票

針對每一個投票,Server 都會將別人的投票和自己的投票進行 PK,計算出 Zxid 最大的 Server,並將該 Server 設置成下一次投票推薦的 Server。

4)統計投票

每次投票結束之後,都會統計所有投票,獲取投票最多的 Server 將成為獲勝者,如果獲勝者的票數超過集群個數的一半,則該 Server 將為推選為 Leader。否則繼續投票,直至 Leader 被選舉出來。

5)改變伺服器狀態

一旦 Leader 確定後,Leader 會通知其他 Follower 集群已經成為 Uptodate 狀態,Follower 在收到 Uptodate 消息後,接收 Client 的請求並開始對外提供服務。

2. 選舉 Leader 的具體實例

上述的選舉過程比較抽象,我們以一個有5個節點的集群為例,目前均為 shutdown 狀態。

在這裡插入圖片描述
按照 Server 的編號依次啟動,看下整個的選舉過程是如何實現的。

1)Server 1 啟動

在這裡插入圖片描述
Server 1 啟動後會提議自己為 Leader 併為自己投票,然後將投票結果發送給其他 Server,由於其他 Server 還未啟動,因此收不到任何反饋信息,此時 Server 1 會處於 Looking 狀態。

2)Server 2 啟動
在這裡插入圖片描述

Server 2 啟動後會提議自己為 Leader 併為自己投票,然後與 Server 1 交換投票結果,由於 Server 2 的編號大於 Server 1,因此 Server 2 勝出。但是,由於投票數未過集群數的一半,兩個 Server 仍然均處於 Looking 狀態。

3)Server 3 啟動
在這裡插入圖片描述
Server 3 啟動後會提議自己為 Leader 併為自己投票,然後與 Server 2、Server 3 交換投票結果,由於 Server 3 的編號最大,因此 Server 3 勝出。此時, Server 3 的票數大於集群數的一半了,因此 Server 3 會更新為 Leader ,Server 1、Server 2 更新為 Follower。

4)Server 4 啟動
在這裡插入圖片描述
Server 4 啟動後會提議自己為 Leader 併為自己投票,然後與 Server 1、Server 2、Server 3 交換投票結果,發現 Server 3 已經成為了 Leader,因此 Server 4 也成為了 Follower。

5)Server 5 啟動
在這裡插入圖片描述

與 Server 4 一樣,Server 5 啟動後會給自己投票,然後與其他 Server 交換信息,發現 Server 3 已經成為了 Leader,因此 Server 5 也成為了 Follower。

投票 vote 的數據結構

  • id:伺服器ID,用來唯一標識 ZooKeeper 集群中的伺服器;
  • Zxid:事務ID,用來唯一標識一次伺服器狀態的變更;
  • electionEpoch:代表當前伺服器的選舉輪次,是一個自增序列;
  • peerEpoch:被推舉的 Leader 的選舉輪次;
  • state:當前伺服器的狀態。

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 從演化歷史看大型網站架構 楊傳偉 (石家莊鐵道大學信息科學與技術學院,河北省,石家莊市,050043) 摘 要:本文以大型網站系統的特點、大型網站架構演化發展歷程以及大數據與高併發為切入和論述點,由淺入深、由簡到繁地對大型網站架構設計展開敘述,首先通述其特點,之後介紹大型網站架構的歷史發展歷程,從其 ...
  • 一些必須提前知道的概念 patition kafka日誌文件是以patition在物理存儲上分割的 是topic物理上的分組,一個topic可以分為多個partition,每個partition是一個有序的隊列 是以文件夾的形式存儲在具體Broker本機上 LEO 表示每個partition的log ...
  • MVC架構設計淺析 楊傳偉 (石家莊鐵道大學信息科學與技術學院,河北省,石家莊市,050043) 摘 要:本文以圖書管理系統為案例(當前主流框架SpringMVC的原理來分析MVC的設計理念等),深入淺出地分析常用的WEB設計模式MVC。將從MVC的歷史、MVC每一層的作用,MVC能為我們帶來什麼好 ...
  • 單例模式 單例模式一般用於全局只需要一個唯一的實例的情況。 例如說,日誌讀寫的功能,一般來說全局只需一個日誌讀寫實例,然後其他的類實例去獲取這個實例進行日誌讀寫。 又例如說,有一個協作的功能,需要各個模塊發送給主控制器,主控制器需要做成單例,這樣子模塊之間操作控制器就是操作實際主控制器的內容。 怎麼 ...
  • 操作系統:Windows10 Python版本:3.9.2 vosk是一個離線開源語音識別工具,它可以識別16種語言,包括中文。 這裡記錄下使用vosk進行中文識別的過程,以便後續查閱。 vosk地址:https://alphacephei.com/vosk/ 使用vosk-server進行語音識別 ...
  • 衡量運行時間 很多時候你需要計算某段代碼執行所需的時間,可以使用 time 模塊來實現這個功能。 import time startTime = time.time() # write your code or functions calls endTime = time.time() totalT ...
  • 知識回顧 上一篇介紹了Spring中三級緩存的singletonObjects、earlySingletonObjects、singletonFactories,Spring在處理迴圈依賴時在實例化後屬性填充前將一個lambda表達式放在了三級緩存中,後續在獲取時進行了判斷,如果不需要進行對象代理, ...
  • 1. Netty源碼研究筆記(2)——Bootstrap系列 顧名思義,Bootstrap是netty提供給使用者的腳手架,類似於Spring的ApplicationContext,通過Bootstrap我們使用一些自定義選項,將相關的組件打包起來,從而快速的啟動伺服器、客戶端。 Bootstrap ...
一周排行
    -Advertisement-
    Play Games
  • 概述:在C#中,++i和i++都是自增運算符,其中++i先增加值再返回,而i++先返回值再增加。應用場景根據需求選擇,首碼適合先增後用,尾碼適合先用後增。詳細示例提供清晰的代碼演示這兩者的操作時機和實際應用。 在C#中,++i 和 i++ 都是自增運算符,但它們在操作上有細微的差異,主要體現在操作的 ...
  • 上次發佈了:Taurus.MVC 性能壓力測試(ap 壓測 和 linux 下wrk 壓測):.NET Core 版本,今天計劃準備壓測一下 .NET 版本,來測試並記錄一下 Taurus.MVC 框架在 .NET 版本的性能,以便後續持續優化改進。 為了方便對比,本文章的電腦環境和測試思路,儘量和... ...
  • .NET WebAPI作為一種構建RESTful服務的強大工具,為開發者提供了便捷的方式來定義、處理HTTP請求並返迴響應。在設計API介面時,正確地接收和解析客戶端發送的數據至關重要。.NET WebAPI提供了一系列特性,如[FromRoute]、[FromQuery]和[FromBody],用 ...
  • 原因:我之所以想做這個項目,是因為在之前查找關於C#/WPF相關資料時,我發現講解圖像濾鏡的資源非常稀缺。此外,我註意到許多現有的開源庫主要基於CPU進行圖像渲染。這種方式在處理大量圖像時,會導致CPU的渲染負擔過重。因此,我將在下文中介紹如何通過GPU渲染來有效實現圖像的各種濾鏡效果。 生成的效果 ...
  • 引言 上一章我們介紹了在xUnit單元測試中用xUnit.DependencyInject來使用依賴註入,上一章我們的Sample.Repository倉儲層有一個批量註入的介面沒有做單元測試,今天用這個示例來演示一下如何用Bogus創建模擬數據 ,和 EFCore 的種子數據生成 Bogus 的優 ...
  • 一、前言 在自己的項目中,涉及到實時心率曲線的繪製,項目上的曲線繪製,一般很難找到能直接用的第三方庫,而且有些還是定製化的功能,所以還是自己繪製比較方便。很多人一聽到自己畫就害怕,感覺很難,今天就分享一個完整的實時心率數據繪製心率曲線圖的例子;之前的博客也分享給DrawingVisual繪製曲線的方 ...
  • 如果你在自定義的 Main 方法中直接使用 App 類並啟動應用程式,但發現 App.xaml 中定義的資源沒有被正確載入,那麼問題可能在於如何正確配置 App.xaml 與你的 App 類的交互。 確保 App.xaml 文件中的 x:Class 屬性正確指向你的 App 類。這樣,當你創建 Ap ...
  • 一:背景 1. 講故事 上個月有個朋友在微信上找到我,說他們的軟體在客戶那邊隔幾天就要崩潰一次,一直都沒有找到原因,讓我幫忙看下怎麼回事,確實工控類的軟體環境複雜難搞,朋友手上有一個崩潰的dump,剛好丟給我來分析一下。 二:WinDbg分析 1. 程式為什麼會崩潰 windbg 有一個厲害之處在於 ...
  • 前言 .NET生態中有許多依賴註入容器。在大多數情況下,微軟提供的內置容器在易用性和性能方面都非常優秀。外加ASP.NET Core預設使用內置容器,使用很方便。 但是筆者在使用中一直有一個頭疼的問題:服務工廠無法提供請求的服務類型相關的信息。這在一般情況下並沒有影響,但是內置容器支持註冊開放泛型服 ...
  • 一、前言 在項目開發過程中,DataGrid是經常使用到的一個數據展示控制項,而通常表格的最後一列是作為操作列存在,比如會有編輯、刪除等功能按鈕。但WPF的原始DataGrid中,預設只支持固定左側列,這跟大家習慣性操作列放最後不符,今天就來介紹一種簡單的方式實現固定右側列。(這裡的實現方式參考的大佬 ...