自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

深入淺出 Zookeeper 中的 ZAB 協(xié)議

網(wǎng)絡(luò) 無線技術(shù)
本篇盡量用大白話+畫圖的方式進(jìn)行講解Zookeeper 中的 ZAB 協(xié)議,希望能給大家?guī)韱l(fā)。

ZAB 協(xié)議的全稱是 Zookeeper Atomic Broadcase,原子廣播協(xié)議。

作用:通過這個(gè) ZAB 協(xié)議可以進(jìn)行集群間主備節(jié)點(diǎn)的數(shù)據(jù)同步,保證數(shù)據(jù)的一致性。

在講解 ZAB 協(xié)議之前,我們必須要了解 Zookeeper 的各節(jié)點(diǎn)的角色。

Zookeeper 各節(jié)點(diǎn)的角色

Leader:

  • 負(fù)責(zé)處理客戶端發(fā)送的讀、寫事務(wù)請求。這里的事務(wù)請求可以理解這個(gè)請求具有事務(wù)的 ACID 特性。
  • 同步寫事務(wù)請求給其他節(jié)點(diǎn),且需要保證事務(wù)的順序性。
  • 狀態(tài)為 LEADING。

Follower:

  • 負(fù)責(zé)處理客戶端發(fā)送的讀請求
  • 轉(zhuǎn)發(fā)寫事務(wù)請求給 Leader。
  • 參與 Leader 的選舉。
  • 狀態(tài)為 FOLLOWING。

Observer:

  • 和 Follower 一樣,唯一不同的是,不參與 Leader 的選舉,且狀態(tài)為 OBSERING。
  • 可以用來線性擴(kuò)展讀的 QPS。

啟動(dòng)階段,如何選 Leader?

Zookeeper 剛啟動(dòng)的時(shí)候,多個(gè)節(jié)點(diǎn)需要找出一個(gè) Leader。怎么找呢,就是用投票。

比如集群中有兩個(gè)節(jié)點(diǎn),A 和 B,原理圖如下所示:

  • 節(jié)點(diǎn) A 先投票給自己,投票信息包含節(jié)點(diǎn) id(SID) 和一個(gè) ZXID,如 (1,0)。SID 是配置好的,且唯一,ZXID 是唯一的遞增編號。
  • 節(jié)點(diǎn) B 先投票給自己,投票信息為(2,0)。
  • 然后節(jié)點(diǎn) A 和 B 將自己的投票信息投票給集群中所有節(jié)點(diǎn)。
  • 節(jié)點(diǎn) A 收到節(jié)點(diǎn) B 的投票信息后,檢查下節(jié)點(diǎn) B 的狀態(tài)是否是本輪投票,以及是否是正在選舉(LOOKING)的狀態(tài)。
  • 投票 PK:節(jié)點(diǎn) A 會(huì)將自己的投票和別人的投票進(jìn)行 PK,如果別的節(jié)點(diǎn)發(fā)過來的 ZXID 較大,則把自己的投票信息更新為別的節(jié)點(diǎn)發(fā)過來的投票信息,如果 ZXID 相等,則比較 SID。這里節(jié)點(diǎn) A 和 節(jié)點(diǎn) B 的 ZXID 相同,SID 的話,節(jié)點(diǎn) B 要大些,所以節(jié)點(diǎn) A 更新投票信息為(2,0),然后將投票信息再次發(fā)送出去。而節(jié)點(diǎn) B 不需要更新投票信息,但是下一輪還需要再次將投票發(fā)出去。

這個(gè)時(shí)候節(jié)點(diǎn) A 的投票信息為(2,0),如下圖所示:

  • 統(tǒng)計(jì)投票:每一輪投票,都會(huì)統(tǒng)計(jì)每臺(tái)節(jié)點(diǎn)收到的投票信息,判斷是否有過半的節(jié)點(diǎn)收到了相同的投票信息。節(jié)點(diǎn) A 和 節(jié)點(diǎn) B 收到的投票信息都為(2,0),且數(shù)量來說,大于一半節(jié)點(diǎn)的數(shù)量,所以將節(jié)點(diǎn) B 選出來作為 Leader。
  • 更新節(jié)點(diǎn)狀態(tài):節(jié)點(diǎn) A 作為 Follower,更新狀態(tài)為 FOLLOWING,節(jié)點(diǎn) B 作為 Leader,更新狀態(tài)為 LEADING。

運(yùn)行期間,Leader 宕機(jī)了怎么辦?

在 Zookeeper 運(yùn)行期間,Leader 會(huì)一直保持為 LEADING 狀態(tài),直到 Leader 宕機(jī)了,這個(gè)時(shí)候就要重新選 Leader,而選舉過程和啟動(dòng)階段的選舉過程基本一致。

需要注意的點(diǎn):

  • 剩下的 Follower 進(jìn)行選舉,Observer 不參與選舉。
  • 投票信息中的 zxid 用的是本地磁盤日志文件中的。如果這個(gè)節(jié)點(diǎn)上的 zxid 較大,就會(huì)被當(dāng)選為 Leader。如果 Follower 的 zxid 都相同,則 Follower 的節(jié)點(diǎn) id 較大的會(huì)被選為 Leader。

節(jié)點(diǎn)之間如何同步數(shù)據(jù)的?

不同的客戶端可以分別連接到主節(jié)點(diǎn)或備用節(jié)點(diǎn)。

而客戶端發(fā)送讀寫請求時(shí)是不知道自己連的是Leader 還是 Follower,如果客戶端連的是主節(jié)點(diǎn),發(fā)送了寫請求,那么 Leader 執(zhí)行 2PC(兩階段提交協(xié)議)同步給其他 Follower 和 Observer 就可以了。但是如果客戶端連的是 Follower,發(fā)送了寫請求,那么 Follower 會(huì)將寫請求轉(zhuǎn)發(fā)給 Leader,然后 Leader 再進(jìn)行 2PC 同步數(shù)據(jù)給 Follower。

兩階段提交協(xié)議:

  • 第一階段:Leader 先發(fā)送 proposal 給 Follower,F(xiàn)ollower 發(fā)送 ack 響應(yīng)給 Leader。如果收到的 ack 過半,則進(jìn)入下一階段。
  • 第二階段: Leader 從磁盤日志文件中加載數(shù)據(jù)到內(nèi)存中,Leader 發(fā)送 commit 消息給 Follower,F(xiàn)ollower 加載數(shù)據(jù)到內(nèi)存中。

我們來看下 Leader 同步數(shù)據(jù)的流程:

  • ① 客戶端發(fā)送寫事務(wù)請求。
  • ② Leader 收到寫請求后,轉(zhuǎn)化為一個(gè) "proposal01:zxid1" 事務(wù)請求,存到磁盤日志文件。
  • ③ 發(fā)送 proposal 給其他 Follower。
  • ④ Follower 收到 proposal 后,F(xiàn)ollower 寫磁盤日志文件。

接著我們看下 Follower 收到 Leader 發(fā)送的 proposal 事務(wù)請求后,怎么處理的:

  • ⑤ Follower 返回 ack 給 Leader。
  • ⑥ Leader 收到超過一半的 ack,進(jìn)行下一階段
  • ⑦ Leader 將磁盤中的日志文件的 proposal 加載到 znode 內(nèi)存數(shù)據(jù)結(jié)構(gòu)中。
  • ⑧ Leader 發(fā)送 commit 消息給所有 Follower 和 Observer。
  • ⑨ Follower 收到 commit 消息后,將 磁盤中數(shù)據(jù)加載到 znode 內(nèi)存數(shù)據(jù)結(jié)構(gòu)中。

現(xiàn)在 Leader 和 Follower 的數(shù)據(jù)都是在內(nèi)存數(shù)據(jù)中的,且是一致的,客戶端從 Leader 和 Follower 讀到的數(shù)據(jù)都是一致的。

ZAB 的順序一致性怎么做到的?

Leader 發(fā)送 proposal 時(shí),其實(shí)會(huì)為每個(gè) Follower 創(chuàng)建一個(gè)隊(duì)列,都往各自的隊(duì)列中發(fā)送 proposal。

如下圖所示是 Zookeeper 的消息廣播流程:

客戶端發(fā)送了三條寫事務(wù)請求,對應(yīng)的 proposal 為:

proposal01:zxid1
proposal02:zxid2
proposal03:zxid3

Leader 收到請求后,依次放到隊(duì)列中,然后 Follower 依次從隊(duì)列中獲取請求,這樣就保證了數(shù)據(jù)的順序性。

Zookeeper 到底是不是強(qiáng)一致性?

官方定義:順序一致性。

不保證強(qiáng)一致性,為什么呢?

因?yàn)?Leader 再發(fā)送 commit 消息給所有 Follower 和 Observer 后,它們并不是同時(shí)完成 commit 的。

比如因?yàn)榫W(wǎng)絡(luò)原因,不同節(jié)點(diǎn)收到的 commit 較晚,那么提交的時(shí)間也較晚,就會(huì)出現(xiàn)多個(gè)節(jié)點(diǎn)的數(shù)據(jù)不一致,但是經(jīng)過短暫的時(shí)間后,所有節(jié)點(diǎn)都 commit 后,數(shù)據(jù)就保持同步了。

另外 Zookeeper 支持強(qiáng)一致性,就是手動(dòng)調(diào)用 sync 方法來保證所有節(jié)點(diǎn)都 commit 才算成功。

這里有個(gè)問題:如果某個(gè)節(jié)點(diǎn) commit 失敗,那么 Leader 會(huì)進(jìn)行重試嗎?如何保證數(shù)據(jù)的一致性?歡迎討論。

Leader 宕機(jī)數(shù)據(jù)丟失問題

第一種情況:

假設(shè) Leader 已經(jīng)將消息寫入了本地磁盤,但是還沒有發(fā)送 proposal 給 Follower,這個(gè)時(shí)候 Leader 宕機(jī)了。

那就需要選新的 Leader,新 Leader 發(fā)送 proposal 的時(shí)候,包含的 zxid 自增規(guī)律會(huì)發(fā)生一次變化:

  • zxid 的高 32 位自增 1 一次,高 32 位代表 Leader 的版本號。
  • zxid 的低 32 位自增 1,后續(xù)還是繼續(xù)保持自增長。

當(dāng)老 Leader 恢復(fù)后,會(huì)轉(zhuǎn)成 Follower,Leader 發(fā)送最新的 proposal 給它時(shí),發(fā)現(xiàn)本地磁盤的 proposal 的 zxid 的高 32 位小于新 Leader 發(fā)送的 proposal,就丟棄自己的 proposal。

第二種情況:

如果 Leader 成功發(fā)送了 commit 消息給 Follower,但是所有或者部分 Follower 還沒來得及 commit 這個(gè) proposal,也就是加載磁盤中的 proposal 到 內(nèi)存中,這個(gè)時(shí)候 Leader 宕機(jī)了。

那么就需要選出磁盤日志中 zxid 最大的 Follower,如果 zxid 相同,則比較節(jié)點(diǎn) id,節(jié)點(diǎn) id 大的作為 Leader。

本篇盡量用大白話+畫圖的方式進(jìn)行講解,希望能給大家?guī)韱l(fā)。

責(zé)任編輯:趙寧寧 來源: 悟空聊架構(gòu)
相關(guān)推薦

2018-01-25 18:30:09

Zookeeper分布式數(shù)據(jù)

2021-03-16 08:54:35

AQSAbstractQueJava

2011-07-04 10:39:57

Web

2023-05-05 18:33:15

2009-11-30 16:46:29

學(xué)習(xí)Linux

2019-11-11 14:51:19

Java數(shù)據(jù)結(jié)構(gòu)Properties

2022-12-02 09:13:28

SeataAT模式

2017-07-02 18:04:53

塊加密算法AES算法

2019-01-07 15:29:07

HadoopYarn架構(gòu)調(diào)度器

2021-07-20 15:20:02

FlatBuffers阿里云Java

2012-05-21 10:06:26

FrameworkCocoa

2022-09-26 09:01:15

語言數(shù)據(jù)JavaScript

2014-08-05 09:27:20

TCP網(wǎng)絡(luò)協(xié)議

2023-04-06 07:57:29

RPC服務(wù)網(wǎng)絡(luò)協(xié)議

2010-01-27 16:13:43

2023-03-20 09:48:23

ReactJSX

2019-11-14 09:53:30

Set集合存儲(chǔ)

2009-12-25 15:49:43

Linux rescu

2022-01-11 07:52:22

CSS 技巧代碼重構(gòu)

2019-12-04 10:13:58

Kubernetes存儲(chǔ)Docker
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號