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

面試官上來就問 ZAB 協(xié)議,瑟瑟發(fā)抖…

網(wǎng)絡(luò) 網(wǎng)絡(luò)管理
ZAB 協(xié)議是為分布式協(xié)調(diào)服務(wù)ZooKeeper專門設(shè)計(jì)的一種支持崩潰恢復(fù)的一致性協(xié)議。基于該協(xié)議,ZooKeeper 實(shí)現(xiàn)了一種主從模式的系統(tǒng)架構(gòu)來保持集群中各個(gè)副本之間的數(shù)據(jù)一致性。

[[391275]]

Zookeeper 是通過 ZAB 一致性協(xié)議來實(shí)現(xiàn)分布式事務(wù)的最終一致性。

ZAB 協(xié)議介紹

ZAB 全稱為 Zookeeper Atomic Broadcast(Zookeeper 原子廣播協(xié)議)

ZAB 協(xié)議是為分布式協(xié)調(diào)服務(wù)ZooKeeper專門設(shè)計(jì)的一種支持崩潰恢復(fù)的一致性協(xié)議。基于該協(xié)議,ZooKeeper 實(shí)現(xiàn)了一種主從模式的系統(tǒng)架構(gòu)來保持集群中各個(gè)副本之間的數(shù)據(jù)一致性。

ZAB的消息廣播過程使用的是原子廣播協(xié)議,類似于二階段提交。針對(duì)客戶端的請(qǐng)求,Leader服務(wù)器生成對(duì)應(yīng)的事務(wù)提議,并將其發(fā)送給集群中所有的 Follower 服務(wù)器。然后收集各自的選票,最后進(jìn)行事務(wù)提交。如圖:


在 ZAB 協(xié)議中二階段提交,移除了中斷邏輯。所有的 Follower 服務(wù)器要么正常反饋 Leader 提出的事務(wù)提議,要么就拋棄 Leader 服務(wù)器。同時(shí),我們可以在過半的 Follower 服務(wù)器已經(jīng)反饋 ACK 后,就開始提交事務(wù)提議了。

Leader 服務(wù)器會(huì)為事務(wù)提議分配一個(gè)全局單調(diào)遞增的 ID,稱為事務(wù) ID(ZXID)。由于 ZAB 協(xié)議需要保證每一個(gè)消息嚴(yán)格的因果關(guān)系,因此需要將每一個(gè)事務(wù)提議按照其 ZXID 的先后順序進(jìn)行處理。

在消息廣播過程中,Leader 服務(wù)器會(huì)為每一個(gè) Follower 服務(wù)器分配一個(gè)隊(duì)列,然后將事務(wù)提議依次放入到這些隊(duì)列中去,并且根據(jù) FIFO 的策略進(jìn)行消息發(fā)送。

每一個(gè) Follower 服務(wù)器接收到這個(gè)事務(wù)提議后,會(huì)把該事務(wù)提議以事務(wù)日志的形式寫入到本地磁盤中,并且寫入成功后,反饋給 Leader 服務(wù)器 ACK。

當(dāng) Leader 服務(wù)器收到過半 Follower 服務(wù)器的 ACK,就發(fā)送一個(gè) COMMIT 消息,同時(shí) Leader 自身完成事務(wù)提交,F(xiàn)ollower 服務(wù)器接收到 COMMIT 消息后,也進(jìn)行事務(wù)提交。

之所以采用原子廣播協(xié)議協(xié)議,是為了保證分布式數(shù)據(jù)一致性。過半的節(jié)點(diǎn)數(shù)據(jù)保存一致性。

消息廣播

你可以認(rèn)為消息廣播機(jī)制是簡(jiǎn)化版的 2PC協(xié)議,就是通過如下的機(jī)制保證事務(wù)的順序一致性的。


客戶端提交事務(wù)請(qǐng)求時(shí) Leader 節(jié)點(diǎn)為每一個(gè)請(qǐng)求生成一個(gè)事務(wù) Proposal,將其發(fā)送給集群中所有的 Follower 節(jié)點(diǎn),收到過半 Follower的反饋后開始對(duì)事務(wù)進(jìn)行提交,ZAB 協(xié)議使用了原子廣播協(xié)議;在 ZAB 協(xié)議中只需要得到過半的 Follower 節(jié)點(diǎn)反饋 Ack 就可以對(duì)事務(wù)進(jìn)行提交,這也導(dǎo)致了 Leader 節(jié)點(diǎn)崩潰后可能會(huì)出現(xiàn)數(shù)據(jù)不一致的情況,ZAB 使用了崩潰恢復(fù)來處理數(shù)字不一致問題;消息廣播使用了TCP 協(xié)議進(jìn)行通訊所有保證了接受和發(fā)送事務(wù)的順序性。廣播消息時(shí) Leader 節(jié)點(diǎn)為每個(gè)事務(wù) Proposal分配一個(gè)全局遞增的 ZXID(事務(wù)ID),每個(gè)事務(wù) Proposal 都按照 ZXID 順序來處理;

Leader 節(jié)點(diǎn)為每一個(gè) Follower 節(jié)點(diǎn)分配一個(gè)隊(duì)列按事務(wù) ZXID 順序放入到隊(duì)列中,且根據(jù)隊(duì)列的規(guī)則 FIFO 來進(jìn)行事務(wù)的發(fā)送。Follower節(jié)點(diǎn)收到事務(wù) Proposal 后會(huì)將該事務(wù)以事務(wù)日志方式寫入到本地磁盤中,成功后反饋 Ack 消息給 Leader 節(jié)點(diǎn),Leader 在接收到過半Follower 節(jié)點(diǎn)的 Ack 反饋后就會(huì)進(jìn)行事務(wù)的提交,以此同時(shí)向所有的 Follower 節(jié)點(diǎn)廣播 Commit 消息,F(xiàn)ollower 節(jié)點(diǎn)收到 Commit 后開始對(duì)事務(wù)進(jìn)行提交;

崩潰恢復(fù)

消息廣播過程中,Leader 崩潰了還能保證數(shù)據(jù)一致嗎?當(dāng) Leader 崩潰會(huì)進(jìn)入崩潰恢復(fù)模式。其實(shí)主要是對(duì)如下兩種情況的處理。

  1. Leader 在復(fù)制數(shù)據(jù)給所有 Follwer 之后崩潰,怎么處理?
  2. Leader 在收到 Ack 并提交了自己,同時(shí)發(fā)送了部分 commit 出去之后崩潰,怎么處理?

針對(duì)此問題,ZAB 定義了 2 個(gè)原則:

  1. ZAB 協(xié)議確保執(zhí)行那些已經(jīng)在 Leader 提交的事務(wù)最終會(huì)被所有服務(wù)器提交。
  2. ZAB 協(xié)議確保丟棄那些只在 Leader 提出/復(fù)制,但沒有提交的事務(wù)。

至于如何實(shí)現(xiàn)確保提交已經(jīng)被 Leader 提交的事務(wù),同時(shí)丟棄已經(jīng)被跳過的事務(wù)呢?核心是通過 ZXID 來進(jìn)行處理。在崩潰過后進(jìn)行恢復(fù)的時(shí)候會(huì)選擇最大的 zxid 作為恢復(fù)的快照。這樣的好處是: 可以省略事務(wù)提交的檢查和事務(wù)的丟棄工作以提升效率

數(shù)據(jù)同步

完成Leader選舉之后,在正式開始工作之前,Leader服務(wù)器會(huì)去確認(rèn)事務(wù)日志中所有事務(wù)提議(指已經(jīng)提交的事務(wù)提議)是否都已經(jīng)被過半的機(jī)器提交了,即是否完成數(shù)據(jù)同步。下面是ZAB協(xié)議的 數(shù)據(jù)同步過程。

Leader服務(wù)器為每一個(gè)Follower服務(wù)器準(zhǔn)備一個(gè)隊(duì)列,將那些沒有被Follower服務(wù)器同步的事務(wù)以事務(wù)提議的形式逐個(gè)發(fā)送給Follower服務(wù)器,并在每一個(gè)事務(wù)提議消息后面發(fā)送一個(gè)commit消息,表示該事務(wù)已被提交。

等到Follower服務(wù)器將所有其未同步的事務(wù)提議都從Leader服務(wù)器上面同步過來,并且應(yīng)用到本地?cái)?shù)據(jù)庫后,Leader服務(wù)器就會(huì)將該Follower服務(wù)器加入到真正可用的Follower列表中。

ZXID 的設(shè)計(jì)

ZXID 是一個(gè)64位的數(shù)字, 如下圖所示。


其中低 32 位是一個(gè)簡(jiǎn)單的單調(diào)遞增的計(jì)數(shù)器,Leader 服務(wù)器產(chǎn)生一個(gè)新的事務(wù)提議的時(shí)候,都會(huì)對(duì)該計(jì)數(shù)器 +1。

高 32 位,用來區(qū)分不同的 Leader 服務(wù)器。具體做法是,每選舉產(chǎn)生一個(gè)新的 Leader 服務(wù)器,就會(huì)從 Leader 服務(wù)器的本地日志中取出一個(gè)最大的 ZXID,生成對(duì)應(yīng)的 epoch 值,然后再進(jìn)行加1操作,之后就會(huì)以該值作為新的 epoch。并將低 32 位從 0 開始生成 ZXID。(我理解這里的 epoch 代表的就是一個(gè) Leader 服務(wù)器的標(biāo)志,每次選舉 Leader 服務(wù)器,那么 epoch 值就會(huì)更新,代表是這段時(shí)期由這個(gè)新的 Leader 服務(wù)器進(jìn)行事務(wù)請(qǐng)求的處理)。

ZAB 協(xié)議中通過 epoch 編號(hào)來區(qū)分 Leader 周期變化,能夠有效避免不同 Leader 服務(wù)器使用相同的 ZXID。

下面是我 Leader 節(jié)點(diǎn)的 zxid 生成核心代碼大家可以看一下。

  1. // Leader.java 
  2. void lead() throws IOException, InterruptedException { 
  3.     // .... 
  4.   long epoch = getEpochToPropose(self.getId(), self.getAcceptedEpoch()); 
  5.   zk.setZxid(ZxidUtils.makeZxid(epoch, 0)); 
  6.   // .... 
  7. // 
  8. public long getEpochToPropose(long sid, long lastAcceptedEpoch) throws InterruptedException, IOException { 
  9.   synchronized (connectingFollowers) { 
  10.     // .... 
  11.     if (isParticipant(sid)) { 
  12.       // 將自己加入連接隊(duì)伍中,方便后面判斷 lead 是否有效 
  13.       connectingFollowers.add(sid); 
  14.     } 
  15.     QuorumVerifier verifier = self.getQuorumVerifier(); 
  16.     // 如果有足夠多的 follower 進(jìn)入, 選舉有效,則無需等待,并通過其他等待的線程,類似 Barrier 
  17.     if (connectingFollowers.contains(self.getId()) && verifier.containsQuorum(connectingFollowers)) { 
  18.       waitingForNewEpoch = false
  19.       self.setAcceptedEpoch(epoch); 
  20.       connectingFollowers.notifyAll(); 
  21.     } else { 
  22.       // .... 
  23.       // followers 不夠就進(jìn)入等待, 超時(shí)時(shí)間為 initLimit 
  24.       while (waitingForNewEpoch && cur < end && !quitWaitForEpoch) { 
  25.         connectingFollowers.wait(end - cur); 
  26.         cur = Time.currentElapsedTime(); 
  27.       } 
  28.       // 超時(shí)退出,重新選舉 
  29.       if (waitingForNewEpoch) { 
  30.         throw new InterruptedException("Timeout while waiting for epoch from quorum"); 
  31.       } 
  32.     } 
  33.     return epoch; 
  34.   } 
  35. // ZxidUtils 
  36. public static long makeZxid(long epoch, long counter) { 
  37.   return (epoch << 32L) | (counter & 0xffffffffL); 

ZAB 協(xié)議實(shí)現(xiàn)

寫數(shù)據(jù)的過程

下面我梳理了 zookeeper 源碼中寫數(shù)據(jù)的過程,如下圖所示:


參考資料

https://www.cnblogs.com/veblen/p/10985676.html

https://zookeeper.apache.org

 

責(zé)任編輯:姜華 來源: 運(yùn)維開發(fā)故事
相關(guān)推薦

2021-03-25 08:45:15

MySQL

2021-09-16 07:55:39

Kafka事務(wù)執(zhí)行

2020-12-18 08:40:44

Chrome瀏覽器渲染

2021-01-11 07:48:59

CTO團(tuán)隊(duì)職場(chǎng)

2022-07-03 06:26:53

JetBrains插件

2020-09-18 10:00:33

iOS蘋果瀏覽器

2020-11-23 10:06:00

互聯(lián)網(wǎng)數(shù)據(jù)技術(shù)

2021-01-06 08:34:21

Spring核心組件

2021-05-02 23:13:35

人工智能自動(dòng)化人臉識(shí)別

2019-10-23 09:50:53

微信支付寶

2019-07-15 14:13:58

人工智能職業(yè)被取代

2021-12-08 23:30:14

互聯(lián)網(wǎng)裁員危機(jī)

2019-05-13 09:23:50

GitHub代碼開發(fā)者

2022-11-24 15:05:51

谷歌碼農(nóng)

2017-11-07 11:49:23

工信部套餐運(yùn)營商

2021-05-18 08:32:33

TCPIP協(xié)議

2020-06-22 11:50:38

TCPIP協(xié)議

2025-04-07 03:00:00

Dreamer世界模型

2022-04-22 15:28:22

算法MIT數(shù)據(jù)

2019-07-23 09:30:17

HTTP 2.0HTTP協(xié)議傳輸
點(diǎn)贊
收藏

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