一文看懂 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
  • Dapr Outbox 是1.12中的功能。 本文只介紹Dapr Outbox 執行流程,Dapr Outbox基本用法請閱讀官方文檔 。本文中appID=order-processor,topic=orders 本文前提知識:熟悉Dapr狀態管理、Dapr發佈訂閱和Outbox 模式。 Outbo ...
  • 引言 在前幾章我們深度講解了單元測試和集成測試的基礎知識,這一章我們來講解一下代碼覆蓋率,代碼覆蓋率是單元測試運行的度量值,覆蓋率通常以百分比表示,用於衡量代碼被測試覆蓋的程度,幫助開發人員評估測試用例的質量和代碼的健壯性。常見的覆蓋率包括語句覆蓋率(Line Coverage)、分支覆蓋率(Bra ...
  • 前言 本文介紹瞭如何使用S7.NET庫實現對西門子PLC DB塊數據的讀寫,記錄了使用電腦模擬,模擬PLC,自至完成測試的詳細流程,並重點介紹了在這個過程中的易錯點,供參考。 用到的軟體: 1.Windows環境下鏈路層網路訪問的行業標準工具(WinPcap_4_1_3.exe)下載鏈接:http ...
  • 從依賴倒置原則(Dependency Inversion Principle, DIP)到控制反轉(Inversion of Control, IoC)再到依賴註入(Dependency Injection, DI)的演進過程,我們可以理解為一種逐步抽象和解耦的設計思想。這種思想在C#等面向對象的編 ...
  • 關於Python中的私有屬性和私有方法 Python對於類的成員沒有嚴格的訪問控制限制,這與其他面相對對象語言有區別。關於私有屬性和私有方法,有如下要點: 1、通常我們約定,兩個下劃線開頭的屬性是私有的(private)。其他為公共的(public); 2、類內部可以訪問私有屬性(方法); 3、類外 ...
  • C++ 訪問說明符 訪問說明符是 C++ 中控制類成員(屬性和方法)可訪問性的關鍵字。它們用於封裝類數據並保護其免受意外修改或濫用。 三種訪問說明符: public:允許從類外部的任何地方訪問成員。 private:僅允許在類內部訪問成員。 protected:允許在類內部及其派生類中訪問成員。 示 ...
  • 寫這個隨筆說一下C++的static_cast和dynamic_cast用在子類與父類的指針轉換時的一些事宜。首先,【static_cast,dynamic_cast】【父類指針,子類指針】,兩兩一組,共有4種組合:用 static_cast 父類轉子類、用 static_cast 子類轉父類、使用 ...
  • /******************************************************************************************************** * * * 設計雙向鏈表的介面 * * * * Copyright (c) 2023-2 ...
  • 相信接觸過spring做開發的小伙伴們一定使用過@ComponentScan註解 @ComponentScan("com.wangm.lifecycle") public class AppConfig { } @ComponentScan指定basePackage,將包下的類按照一定規則註冊成Be ...
  • 操作系統 :CentOS 7.6_x64 opensips版本: 2.4.9 python版本:2.7.5 python作為腳本語言,使用起來很方便,查了下opensips的文檔,支持使用python腳本寫邏輯代碼。今天整理下CentOS7環境下opensips2.4.9的python模塊筆記及使用 ...