Zookeeper 集羣角色、原理

Zookeeper 的集羣角色

集羣中的 server 分爲三種角色:leader, follower, observerhtml

file

  • 其中observer是配置zoo.cfg明肯定義的,角色leader 在一個zookeeper集羣中有且只能有一個,是經過內部的選舉機制臨時產生的。
  • leader 是集羣中最重要的角色。負責響應集羣的全部對Zookeeper數據狀態變動的請求。它會將每一個狀態更新請求進行順序管理,以便保證整個集羣內部消息處理的 FIFO,遵循了順序一致性(Sequential Consistency)。
    • leader 內部維護 session ,來自客戶端的鏈接和斷開鏈接,都會被統一followerobserver 轉發給leader處理。
    • leader 內部維護單調遞增的 Zxid(ZooKeeper Transaction Id),針對客戶端鏈接,斷開鏈接,節點的寫操做都會分配一個全局惟一的Zxid,同時這些操做是原子性的,而且是嚴格順序性的,遵循ZAB原子廣播一致性協議完成事務(transaction)操做。若是客戶端的全部寫操做,都會被 follower 統一轉發給leader處理。
  • follower 具備選舉權。負責提供給客戶端讀寫服務,須要響應leader的提議
  • observer 沒有選舉權。主要提供給客戶端讀服務,不提供寫服務,也不須要響應leader的提議。也不須要日誌文件,由於沒有寫服務,沒有持久化的須要。
Server狀態
  • LOOKING,競選狀態。
  • FOLLOWING,隨從狀態,同步leader狀態,參與投票決策提案。
  • OBSERVING,觀察狀態,同步leader狀態,不參與投票決策提案。
  • LEADING,領導者狀態,發起正常消息的提案。

Zookeeper 的存儲

zookeeper中的znode數據都是在內存中優先維護和提供讀服務,當事務被提交以及最終提交都會持久化到磁盤的日誌文件中。node

Zookeeper 的內部網絡拓撲

Zookeeper 在內部網絡中如何實現兩兩鏈接的?算法

file

這裏暫且使用 10.0.2.30,10.0.2.31,10.0.2.32,10.0.2.33 替代 node1,node2,node3,node4,並依次啓動 zookeeper。shell

  • zoo.cfg配置文件
server.1=10.0.2.30:2888:3888
server.2=10.0.2.31:2888:3888
server.3=10.0.2.32:2888:3888
server.4=10.0.2.33:2888:3888

依次使用 netstat 查看網絡鏈接狀況apache

  • node1

file

能夠看出來 node1做爲服務節點,由 node2,node3,node4 經過 3888端口創建鏈接進來。
node1 做爲客戶端鏈接 node3 (目前node3是leader) 的2888端口。編程

  • node2

file

能夠看出來 node2做爲服務節點,由 node3,node4 經過 3888端口創建鏈接進來。
可是 node2 做爲客戶端鏈接node1的3888端口。
node2 做爲客戶端鏈接 node3 (目前node3是leader) 的2888端口。數組

  • node3

file

能夠看出來 node3做爲服務節點,由 node4 經過 3888端口創建鏈接進來。
可是 node3 做爲客戶端鏈接node1,node2 的3888端口。
node3 做爲leader節點,由 node1,node2 ,node4 經過 3888端口創建鏈接進來。
至於爲何 node3能當選 leader 呢?能夠在下面的 選舉過程當中 獲得進一步詳細的闡述。服務器

  • node4

file

能夠看出來 node4 做爲客戶端鏈接node1,node2 ,node3 的3888端口。
node4 做爲客戶端鏈接 node3 (目前node3是leader) 的2888端口。微信

  • 結論
    Zookeeper 在內部網絡中如圖所示,依據zoo.cfg的配置後續的server都逐個鏈接前面的server的3888端口,這樣就造成了兩兩鏈接的拓撲,同時也不冗餘。
    而當leader當選時,會開放2888端口,其餘follower鏈接其2888端口。

ZAB(原子廣播,Zookeeper Atomic Broadcast

https://zookeeper.apache.org/doc/current/zookeeperInternals.html網絡

ZAB(Zookeeper Atomic Broadcast)原子廣播是 Paxos分佈式一致性協議算法(http://zh.wikipedia.org/zh-cn/Paxos) 的一個簡化版本。

首先有如下概念,咱們須要瞭解:

  • 數據包(Packet):經過 FIFO Channel 發送的字節數組。
  • 提案(Proposal):協議的單位。經過與ZooKeeper中的法定server交換數據包來達成協議。大多數提案都包含消息,可是 NEW_LEADER Proposal 提案是不包含消息。
  • 消息(Message):要自動廣播到全部ZooKeeper服務器的字節數組。消息被包含在一個提案(Proposal)中,而且只有在提案(Proposal)被經過後消息纔會最終交付delivered(提交到事務日誌和更新內存的統一視圖)。
  • 法定人員 (Quorum):有 Zookeeper集羣中非observer 角色的全部服務器節點組成,具備投票經過提案(Proposal)的權力。

在 Zookeeper 中提供如下的保證數據的嚴格順序:

  • 傳遞可靠性:若是一個消息被一個server最終交付delivered,那麼這個消息最終也被其餘全部的server最終交付delivered,這裏指最終一致性。
  • 順序全局性:若是一個消息a先於b被一個server最終交付delivered,那麼消息a也是先於b被其餘全部的server最終交付delivered
  • 順序傳遞性:若是消息a先於b被髮送到server,消息b先於c被髮送到server,那麼消息a也是先於c被server接收的。

如上所述,ZooKeeper保證消息的總順序,也保證建議的總順序。

ZooKeeper使用ZooKeeper transaction id (zxid) ,這是一個全局的惟一的ID。提出提案(Proposal)時,全部提案都將附上zxid,進而保證全局的順序性。

  • leader 將提案(Proposal)將發送到全部ZooKeeper服務器。

  • 在法定人員(Quorum)收到後,會確認(acknowledge)回覆這個提案(Proposal)給leader

其中確認acknowledge提案(Proposal)表示服務器已將提案(Proposal)持久化到日誌中。

稍微注意一下:法定人員(Quorum)收到提案(Proposal),只存在確認(acknowledge),或者由於網絡等緣由超時響應,不存在反對(reject)。

  • 只要一但知足半數以上(大於全部法定人員的一半)確認acknowledge後,leader就會進入正式提交(Commit)。

  • 若是提案(Proposal)中包含一條消息,則在提交時將最終交付delivered該消息。

ZooKeeper消息傳遞包括兩個階段:

  • leader選舉(Leader activation):在此階段,leader被選舉出來,集羣開始變爲對外可用狀態,並準備開始提出提案(Proposal)。
  • 活動消息傳遞(Active messaging):在此階段,leader開始接受消息(Message),併發起提案(Proposal),協調和決策以提交(Commit)提案(Proposal)。

leader選舉

leader產生的條件:

  • 具備最新的 Zxid,若是 存在多個server都有最新的Zxid,在投票過程當中選取創建網絡鏈接中 myid最大的。
  • leader 和其鏈接的follower的個數必須知足半數以上(大於全部法定人員的一半)。

file

當集羣中任意具備選舉權的server發現leader掛了:

  • 該 server 會觸發NEW_LEADER Proposal 提案,給本身投票,並經過 ZAB 廣播給全部鏈接的 server。
  • 接受到 NEW_LEADER Proposal 提案的server,若是有被選舉權,則會觸發它的投票行爲:
    • 先比較zxid,最新的勝出,若是zxid相同,再比較myid,最大的勝出。
    • 最後將勝出的內容,經過 ZAB 廣播給全部鏈接的 server。
  • 最終知足leader條件的server,將被選出,同時 follower也被廣播得到 Proposal 的提交。

以上中的 網絡拓撲 爲何 node3能當選 leader 呢?

  • node1 啓動時,給本身投票,由於其餘server尚沒啓動,由於 node1 依然在LOOKING競選狀態。
  • node2 啓動完,給本身投票,同時與 node1 交換了Zxid和myid,node2 勝出,但由於沒有達到半數以上法定人員,因此node1,node2 依然處於LOOKING競選狀態。
  • node3 啓動完,給本身投票,同時與 node1 ,node2 交換了Zxid和myid,node3 勝出,也達到半數以上法定人員(3 > 4/2),所以 node3 被選舉爲 leader
  • node4 啓動完,給本身投票,同時與 node1 ,node2 ,node3交換了Zxid和myid,node3的Zxid最新,所以 node4 追隨 node3。

活動消息傳遞

消息的傳遞通常指寫請求。

file

  • follower 接收到 客戶端的 寫請求後,會轉發給 leader順序處理。
  • leader 收到寫請求,會檢查數據問題,如無問題,建立一個新的提案proposal加入toBeApplied FIFO 隊列,內容是寫請求的消息,並附上全局的ZXid。
  • leader每次toBeApplied FIFO 隊列頭部取到一個提案proposal,經過 ZAB 廣播給全部的 follower,處於 pending 等待回覆。
  • follower 收到提案proposal後,記錄提案proposal持久化到磁盤的日誌文件中,而後確認(acknowledge)回覆這個提案(Proposal)給leader
  • leader處於 pending 等待回覆,一旦收到follower 加上本身的確認(acknowledge)超過半數法定人員(Quorum),就會觸發 Commit階段,發送commit請求給全部的follower,發送info請求全部的observer
    同時,leader將提案proposal放入 committedRequest 隊列,並從toBeApplied FIFO 隊列移出該 提案proposal
  • follower 收到 Commit後,會更新本身的內存數據,統一數據視圖。
  • observer收到info後,會更新本身的內存數據,統一數據視圖。

file

針對客戶端的讀請求,則不須要轉發給leader處理。
固然若是是客戶端的sync命令,則會觸發客戶端鏈接的followerobserverleader請求同步數據狀態。

@SvenAugustus(https://www.flysium.xyz/)
更多請關注微信公衆號【編程不離宗】,專一於分享服務器開發與編程相關的技術乾貨:

相關文章
相關標籤/搜索