Zookeeper:Zookeeper的主從選舉機制

ZAB 協議,全稱 Zookeeper Atomic Broadcast(Zookeeper 原子廣播協議),是為分布式協調服務 ZooKeeper 專門設計的一種支持崩潰恢復的一致性協議。基于該協議,ZooKeeper 實現了一種主從模式的系統架構來保持集群中各個副本之間的數據一致性。當 Zookeeper 集群中的一臺服務器出現以下兩種情況之一時,需要進入 Leader 選舉:(1)服務器初始化啟動;(2)服務器運行期間 Leader 故障。

本篇內容包括:關于 ZAB 協議、Zookeeper 選主時機、Zookeeper 選主機制。


文章目錄

    • 一、關于 ZAB 協議
        • 1、ZAB 協議簡述
        • 2、ZooKeeper 集群中的三個服務器角色
    • 二、Zookeeper 選主時機
        • 1、ZooKeeper 服務器的工作狀態
        • 2、Zookeeper 選主時機
        • 3、FOLLOWING 狀態節點(Follower)的主流程
        • 4、LOOKING 狀態節點的主流程
        • 5、LEADING 狀態節點(Leader)的主流程
    • 三、Zookeeper 選主機制
        • 1、涉及到的相關概念
        • 2、Zookeeper 選舉流程
        • 3、集團初始選舉
        • 4、集群重新選舉
        • 5、選舉流程總結


一、關于 ZAB 協議

1、ZAB 協議簡述

ZAB 協議,全稱 Zookeeper Atomic Broadcast(Zookeeper 原子廣播協議),是為分布式協調服務 ZooKeeper 專門設計的一種支持崩潰恢復的一致性協議。基于該協議,ZooKeeper 實現了一種主從模式的系統架構來保持集群中各個副本之間的數據一致性。

作為分布式共識算法的一員,Zab 算法構成了著名的 ZooKeeper 的基石。與赫赫有名的 Paxos、Raft 一樣,Zab 算法也提供了強一致性的保證。

從設計上看,ZAB 協議和 Raft 很類似。ZooKeeper 集群中,只有一個 Leader 節點,其余均為 Follower 節點。

2、ZooKeeper 集群中的三個服務器角色

Zookeeper 集群中的機器分為以下三種角色:

  • Leader:①、整個 Zookeeper 集群工作機制中的核心,過選舉產生的集群領導者,提供讀寫服務;②、一個 Zookeeper 集群中同一時間只能有一個實際工作的 Leader,它用來維護各個 Follow 與 Observer 之間的心跳;③、Leader 是事務請求的唯一調度和處理者,Follow 接收到事務請求會將請求轉發給 Leader 處理。
  • Follow:①、Follow 只提供讀服務,即只處理非事務請求,它接收到事務請求會轉發給 Leader 服務器;②、它參與 Leader 的選舉,參與事務請求 Proposal 的投票;③、一個 Zookeeper 集群同時可以有多個 Follow。
  • Observer:①、功能和 Follow 基本一致,提供讀服務,即只處理非事務請求,唯一的差別是不參與任何投票(包括事務請求 Proposal 和 Leader 的選舉);②、Observer 的作用主要就是在不影響集群事務處理前提下提升集群的非事務處理。

二、Zookeeper 選主時機

1、ZooKeeper 服務器的工作狀態

ZooKeeper 服務器有四種工作狀態:

  1. LOOKING:競選狀態,尋找 Leader。當服務器處于該狀態時,它會認為當前服務器沒有 Leader,因此需要進入 Leader 選舉狀態。

  2. FOLLOWING:跟隨者狀態。表明當前服務器角色是 Follower。

  3. LEADING:領導者狀態。表明當前服務器角色是 Leader。

  4. OBSERVING:觀察者狀態。表明當前服務器角色是 Observer。

2、Zookeeper 選主時機

當 Zookeeper 集群中的一臺服務器出現以下兩種情況之一時,需要進入 Leader 選舉:(1)服務器初始化啟動;(2)服務器運行期間 Leader 故障。

  1. 服務器初始化啟動:每個節點啟動的時候狀態都是 LOOKING,處于觀望狀態,接下來就是要進行選主了。
  2. 服務器運行期間 Leader 故障:Leader 節點運行后會周期性地向 Follower 發送心跳信息(稱之為 ping)
    1. 如果一個 Follower 未收到 Leader 節點的心跳信息,Follower 節點的狀態會從 FOLLOWING 轉變為 LOOKING;
    2. Leader 節點也會檢測 Follower 節點的狀態,如果多數 Follower 節點不再響應 Leader 節點(可能是 Leader 節點與 Follower 節點之間產生了網絡分區),那么 Leader 節點可能此時也不再是合法的 Leader 了,也必須要進行一次新的選主。

3、FOLLOWING 狀態節點(Follower)的主流程

FOLLOWING 狀態節點(Follower)的主流程:

void followLeader() throws InterruptedException {
try {......while (this.isRunning()) {readPacket(qp);processPacket(qp);}// 如果上面的 while 循環內出現異常// Ps:長時間沒有收到 Leader 的消息也是異常
} catch (Exception e) {// 出現異常就退出了 while 循環// 也就結束了 Follower 的處理流程
}

4、LOOKING 狀態節點的主流程

LOOKING 狀態節點的主流程:

public void run() {while (running) {switch (getPeerState()) {case FOLLOWING:try {setFollower(makeFollower(logFactory));follower.followLeader();} catch (Exception e) {......} finally {follower.shutdown();setFollower(null);// 狀態更新為 LOOKINGupdateServerState();}break;......}
}

5、LEADING 狀態節點(Leader)的主流程

在 Leader 節點的主循環流程中,會判斷多數派節點的消息狀態,如下:

void lead() throws IOException, InterruptedException {......while (true) {......// 判斷每個每個 Follower 節點的狀態// 是否與 Leader 保持同步for (LearnerHandler f : getLearners()) {if (f.synced()) {   syncedAckSet.addAck(f.getSid());}}......}if (!tickSkip && !syncedAckSet.hasAllQuorums()) {// 如果失去了大多數 Follower 節點的認可,就跳出 Leader 主循環,進入選主流程break;}......
}// LearnerHandler::synced() 邏輯
// 即判斷當前是否已經過了期望得到的 Follower 的下一個消息的期限:tickOfNextAckDeadline
public boolean synced() {return isAlive() && leader.self.tick.get() <= tickOfNextAckDeadline;
}

三、Zookeeper 選主機制

1、涉及到的相關概念

# Server id(myid 或 sid):服務器 ID

比如有三臺服務器,編號分別是 1,2,3。編號越大在選擇算法中的權重越大,比如初始化啟動時就是根據服務器 ID 進行比較。

# Zxid:事務ID

服務器中存放的數據的事務 ID,值越大說明數據越新,在選舉算法中數據越新權重越大。

zxid 有兩部分組成:高 32位 是 epoch,低 32位 是 epoch 內的自增 id,由 0 開始。每次選出新的 Leader,epoch 會遞增,同時 zxid 的低 32 位清 0

# Epoch:邏輯時鐘

也叫投票的次數,同一輪投票過程中的邏輯時鐘值是相同的,每投完一次票這個數據就會增加。

2、Zookeeper 選舉流程

選舉大致流程:

  • 初始投票:服務器啟動后,每個 Server 都會給自己投上一票,每次投票會包含所投票服務器的 myid 和 zxid
  • 同步投票結果:集群中的服務器在投票后,會將各自的投票結果同步給集群中其他服務器。
  • 檢查投票有效性:各服務器在收到投票后會檢查投票的有效性,如:是否本輪投票,是否來自 LOOKING 狀態的服務器的投票等。
  • 處理投票:服務器之間會進行投票比對,規則如下:①、優先檢查 zxid,較大的服務器優先作為 Leader;②、如果 zxid 相同,則 myid 較大的服務器作為 Leader;
  • 統計投票結果:每輪投票比對之后都會統計投票結果,確認是否有超過半數的機器都得到相同的投票結果,如果是,則選出 Leader,否則繼續投票。
  • 更改服務器狀態:一旦選出 Leader,每個服務器就會各自更新自己的狀態

3、集團初始選舉

假設我們有服務器 1~5,服務器初始化啟動選主流程(粗略版):

  1. 「服務器1」啟動,發起一次選舉。「服務器1」投自己一票。此時「服務器1」票數一票,不夠半數以上(3票),選舉無法完成,「服務器1」狀態保持為 LOOKING
  2. 「服務器2」啟動,再發起一次選舉。「服務器1」和「服務器2」分別投自己一票并交換選票信息;此時「服務器1」發現「服務器2」的 myid 比自己目前投票推舉的「服務器1」大,更改選票為推舉「服務器2」。此時「服務器1」票數 0 票,服「務器2」票數 2 票,沒有半數以上結果,選舉無法完成,「服務器1」,「服務器2」保持 LOOKING
  3. 「服務器3」啟動,發起一次選舉。此時「服務器1」和「服務器2」都會更改選票為「服務器3」。此次投票結果:「服務器1」、「服務器2」為 0。票,「服務器3」為 3。票。此時「服務器3」的票數已經超過半數,「服務器3」當選成為 Leader。「服務器1」、「服務器2」更改狀態為 FOLLOWING,「服務器3」更改狀態為 LEADING
  4. 「服務器4」啟動,發起一次選舉。此時「服務器1,2,3」已經不是 LOOKING 狀態,不會更改選票信息。交換選票信息結果:「服務器3」為 3 票,「服務器4」為 1 票。此時「服務器4」服從多數,更改選票信息為「服務器3」,并更改狀態為 FOLLOWING
  5. 「服務器5」同「服務器4」。

4、集群重新選舉

Zookeeper 集群運行期間無法和 Leader 保持正常連接時,即如果 Leader 掛了,或者 Leader 服務器故障都會進行新一輪的 Leader 選舉。需要重新選舉時,選舉過程就需要加入數據 id,服務器id,和邏輯時鐘。

img

集群重新選舉時,根據 myid 和 zxid 的大小共同決斷,zxid 更大的優先成為 Leader,選舉的標準(粗略版):

  • 邏輯時鐘小的選舉結果會被忽略,重新投票;
  • 統一邏輯時鐘后,事務 id 大的勝出,當選 Leader;
  • 事務 id 相同的情況下,服務器 id 大的勝出,當選 Leader。

5、選舉流程總結

總結:Zookeeper 集群按 myid 從小到大依次啟動初始化時,在超過半數機器的投票的情況下,誰的 myid 最后,誰就是 Leader,知道這個定律,不同的集群規模我們都可以推算出誰是 Leader。

# 集群初始化時:

  • 集群有 3 臺機器,第 2 大的 myid 所在服務器就是 Leader
  • 集群有 4 臺機器,第 3 大的 myid 所在服務器就是 Leader;
  • 集群有 5 臺機器,第 3 大的 myid 所在服務器就是 Leader;
  • 集群有 6 臺機器,第 4 大的 myid 所在服務器就是 Leader;

集群重新選舉時,根據 myid 和 zxid 的大小共同決斷,zxid 更大的優先成為 Leader。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/535447.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/535447.shtml
英文地址,請注明出處:http://en.pswp.cn/news/535447.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Linux namespace之:uts namespace

理解uts namespace uts(UNIX Time-Sharing System) namespace可隔離hostname和NIS Domain name資源&#xff0c;使得一個宿主機可擁有多個主機名或Domain Name。換句話說&#xff0c;可讓不同namespace中的進程看到不同的主機名。 例如&#xff0c;使用unshare命令(較新版本L…

Zookeeper:事件監聽和通知機制

Zookeeper 允許客戶端向服務端的某個 Znode 注冊一個 Watcher 監聽&#xff0c;當服務端的一些指定事件觸發了這個 Watcher&#xff0c;服務端會向指定客戶端發送一個事件通知來實現分布式的通知功能&#xff0c;然后客戶端根據 Watcher 通知狀態和事件類型做出業務上的改變。 …

Linux namespace之:mount namespace

理解mount namespace 用戶通常使用mount命令來掛載普通文件系統&#xff0c;但實際上mount能掛載的東西非常多&#xff0c;甚至連現在功能完善的Linux系統&#xff0c;其內核的正常運行也都依賴于掛載功能&#xff0c;比如掛載根文件系統/。其實所有的掛載功能和掛載信息都由內…

Linux namespace之:network namespace

理解network namespace network namespace用來隔離網絡環境&#xff0c;「在network namespace中&#xff0c;網絡設備、端口、套接字、網絡協議棧、路由表、防火墻規則等都是獨立的」。 因network namespace中具有獨立的網絡協議棧&#xff0c;因此每個network namespace中都…

Kubernetes 的原理

kubernetes 已經成為容器編排領域的王者&#xff0c;它是基于容器的集群編排引擎&#xff0c;具備擴展集群、滾動升級回滾、彈性伸縮、自動治愈、服務發現等多種特性能力。 本文將帶著大家快速了解 kubernetes &#xff0c;了解我們談論 kubernetes 都是在談論什么。 kuberne…

Zookeeper:實現“分布式鎖”的 Demo

Zookeeper 能保證數據的強一致性&#xff0c;用戶任何時候都可以相信集群中每個節點的數據都是相同的。一個用戶創建一個節點作為鎖&#xff0c;另一個用戶檢測該節點&#xff0c;如果存在&#xff0c;代表別的用戶已經鎖住&#xff0c;如果不存在&#xff0c;則可以創建一個節…

JavaIO流:案例

java.io 包下需要掌握的流有 16 個&#xff0c;本篇內容包括&#xff1a;java.io包下需要掌握的流、Java IO 案例。 文章目錄一、java.io包下需要掌握的流二、Java IO 案例1、Demo 1&#xff08;FileInputStream&#xff09;2、Demo 2&#xff08;FileInputStream&#xff09;3…

比對excel數據

#!/usr/bin/env pythonimport openpyxl from openpyxl.styles import PatternFill from openpyxl.styles import colors from openpyxl.styles import Font, Color aD:/測算單位設置/比對/吉林/tmp001.xlsx bD:/測算單位設置/比對/吉林/國網吉林電力.xlsx cD:/測算單位設置/比對…

CPU 是如何執行任務的

前言 你清楚下面這幾個問題嗎&#xff1f; 有了內存&#xff0c;為什么還需要 CPU Cache&#xff1f; CPU 是怎么讀寫數據的&#xff1f; 如何讓 CPU 能讀取數據更快一些&#xff1f; CPU 偽共享是如何發生的&#xff1f;又該如何避免&#xff1f; CPU 是如何調度任務的&a…

Ansible 的自動化運維

1、Ansible 特點 Ansible 自 2012 年發布以來&#xff0c;很快在全球流行&#xff0c;其特點如下&#xff1a; Ansible 基于 Python 開發&#xff0c;運維工程師對其二次開發相對比較容易&#xff1b; Ansible 豐富的內置模塊&#xff0c;幾乎可以滿足一切要求&#xff1b; …

Shell 信號發送與捕捉

1、Linux信號類型 信號&#xff08;Signal&#xff09;&#xff1a;信號是在軟件層次上對中斷機制的一種模擬&#xff0c;通過給一個進程發送信號&#xff0c;執行相應的處理函數。 進程可以通過三種方式來響應一個信號&#xff1a; 1&#xff09;忽略信號&#xff0c;即對信…

運維面試題總結

集群相關 簡述 ETCD 及其特點&#xff1f; etcd 是 CoreOS 團隊發起的開源項目&#xff0c;是一個管理配置信息和服務發現&#xff08;service discovery&#xff09;的項目&#xff0c;它的目標是構建一個高可用的分布式鍵值&#xff08;key-value&#xff09;數據庫&#x…

詳解設計模式:建造者模式

建造者模式&#xff08;Builder Pattern&#xff09;也叫做生成器模式&#xff0c;是 GoF 的 23 種設計模式的一種&#xff0c;它將一個復雜對象的構建與它的表示分離&#xff0c;使得同樣的構建過程可以創建不同的表示。 當我們需要實列化一個復雜的類&#xff0c;以得到不同結…

圖文并茂 VLAN 詳解,讓你看一遍就理解 VLAN

一、為什么需要VLAN 1.1、什么是VLAN? VLAN(Virtual LAN)&#xff0c;翻譯成中文是“虛擬局域網”。LAN可以是由少數幾臺家用計算機構成的網絡&#xff0c;也可以是數以百計的計算機構成的企業網絡。VLAN所指的LAN特指使用路由器分割的網絡——也就是廣播域。 在此讓我們先復習…

認識VLAN,并學會VLAN的劃分和網絡配置實例

VLAN的劃分和網絡的配置實例 1、VLAN基礎知識 VLAN&#xff08;Virtual Local Area Network&#xff09;的中文名為&#xff1a;“虛擬局域網”&#xff0c;注意和VPN&#xff08;虛擬專用網&#xff09;進行區分。 VLAN是一種將局域網設備從邏輯上劃分&#xff08;不是從物…

VLAN劃分及配置注意事項

VLAN&#xff08;Virtual Local Area Network&#xff09;即虛擬局域網&#xff0c;是將一個物理的LAN在邏輯上劃分成多個廣播域的通信技術。VLAN內的主機間可以直接通信&#xff0c;而VLAN間不能直接通信&#xff0c;從而將廣播報文限制在一個VLAN內。VLAN之間的通信是通過第3…

Docker原理剖析

一、簡介 1、了解Docker的前生LXC LXC為Linux Container的簡寫。可以提供輕量級的虛擬化&#xff0c;以便隔離進程和資源&#xff0c;而且不需要提供指令解釋機制以及全虛擬化的其他復雜性。相當于C中的NameSpace。容器有效地將由單個操作系統管理的資源劃分到孤立的組中&#…

獲取Linux內存、cpu、磁盤IO等信息

#!/bin/bash # 獲取要監控的本地服務器IP地址 IPifconfig | grep inet | grep -vE inet6|127.0.0.1 | awk {print $2} echo "IP地址&#xff1a;"$IP# 獲取cpu總核數 cpu_numgrep -c "model name" /proc/cpuinfo echo "cpu總核數&#xff1a;"$c…

Docker容器網絡解析

Docker 容器網絡的發展歷史 在 Dokcer 發布之初&#xff0c;Docker 是將網絡、管理、安全等集成在一起的&#xff0c;其中網絡模塊可以為容器提供橋接網絡、主機網絡等簡單的網絡功能。 從 1.7 版本開始&#xff0c;Docker正是把網絡和存儲這兩部分的功能都以插件化形式剝離出來…

將指定excel的一列數據提取到另一個excel的指定列

#!/usr/bin/env python import openpyxl bjD:/地市縣公司/西藏臺賬數據分析-設備臺帳分析.xlsx wb openpyxl.load_workbook (bj) get_sheets wb.sheetnames #print(get_sheets) TA01TA01 TA02TA02 TA03TA03 TE01TE01 YG201YG201 YG202YG202 YG203YG203 YG204YG204 YG205YG205…