Zookeeper學習系列【三】Zookeeper 集羣架構、讀寫機制以及一致性原理(ZAB協議)

前言

同學們,在上一章中,我們主要講了Zookeeper兩種啓動模式以及具體如何搭建。本章內容主要講的是集羣相關的原理內容,第一章可以當做是Zookeeper原理篇的基礎部分,本章則是Zookeeper原理篇進階部分,有關於Zookeeper集羣的讀寫機制、ZAB協議的知識解析。

本篇的內容主要包含以下幾點:

  • Zookeeper 集羣架構
  • Zookeeper 讀寫機制
  • ZAB協議
  • 關於Zookeeper 集羣的一些其他討論

    • Zookeeper(讀性能)可伸縮性 和 Observer節點
    • Zookeeper 與 CAP 理論
    • Zookeeper 作爲 服務註冊中心的侷限性

一、Zookeeper 集羣架構

接下來我們來說一說Zookeeper的集羣架構。

Zookeeper 集羣中的角色

第一章提過,Zookeeper中,能改變ZooKeeper服務器狀態的操作稱爲事務操作。一般包括數據節點創建與刪除、數據內容更新和客戶端會話創建與失效等操作
  • Leader 領導者 :Leader 節點負責Zookeeper集羣內部投票的發起和決議(一次事務操作),更新系統的狀態;同時它也能接收並且響應Client端發送的請求。
  • Learner 學習者

    • Follower 跟隨者 : Follower 節點用於接收並且響應Client端的請求,如果是事務操作,會將請求轉發給Leader節點,發起投票,參與集羣的內部投票,
    • Observer 觀察者:Observer 節點功能和Follower相同,只是Observer 節點不參與投票過程,只會同步Leader節點的狀態。
  • Client 客戶端

Zookeeper 通過複製來實現高可用。在上一章提到的集羣模式(replicated mode)下,以Leader節點爲準,Zookeeper的ZNode樹上面的每一個修改都會被同步(複製)到其他的Server 節點上面。

上面實際上只是一個概念性的簡單敘述,在看完下文的讀寫機制ZAB協議的兩種模式之後,你就會對這幾種角色有一個更加深刻的認識。

二、Zookeeper 讀寫機制

讀寫流程

下圖就是集羣模式下一個Zookeeper Server節點提供讀寫服務的一個流程。

如上圖所示,每個Zookeeper Server節點除了包含一個請求處理器來處理請求以外,都會有一個內存數據庫(ReplicatedDatabase) 用於持久化數據。ReplicatedDatabase 包含了整個Data Tree。

來自於Client的讀服務(Read Requst),是直接由對應Server的本地副本來進行服務的。

至於來自於Client的寫服務(Write Requst),因爲Zookeeper要保證每臺Server的本地副本是一致的(單一系統映像),需要通過一致性協議(後文提到的ZAB協議)來處理,成功處理的寫請求(數據更新)會先序列化到每個Server節點的本地磁盤(爲了再次啓動的數據恢復)再保存到內存數據庫中。

集羣模式下,Zookeeper使用簡單的同步策略,通過以下三條基本保證來實現數據的一致性

  • 全局串行化所有的寫操作

    串行化可以把變量包括對象,轉化成連續bytes數據. 你可以將串行化後的變量存在一個文件裏或在網絡上傳輸. 然後再反串行化還原爲原來的數據。
  • 保證同一客戶端的指令被FIFO執行(以及消息通知的FIFO)

    FIFO -先入先出
  • 自定義的原子性消息協議

    簡單來說,對數據的寫請求,都會被轉發到Leader節點來處理,Leader節點會對這次的更新發起投票,並且發送提議消息給集羣中的其他節點,當半數以上的Follower節點將本次修改持久化之後,Leader 節點會認爲這次寫請求處理成功了,提交本次的事務。

樂觀鎖

Zookeeper 的核心思想就是,提供一個非鎖機制的Wait Free 的用於分佈式系統同步的核心服務。其核心對於文件、數據的讀寫服務,並不提供加鎖互斥的服務

但是由於Zookeeper的每次更新操作都會更新ZNode的版本(詳見第一章),也就是客戶端可以自己基於版本的對比,來實現更新數據時的加鎖邏輯。例如下圖。

就像我們更新數據庫時,會新增一個version字段,通過更新前後的版本對比來實現樂觀鎖。

三、ZAB協議

終於到了ZAB協議,講述完ZAB協議,大家對Zookeeper的一些特性會有更深的體會,對本文的其他內容也會有更透徹的理解。

ZAB 協議是爲分佈式協調服務ZooKeeper專門設計的一種支持崩潰恢復一致性協議,這個機制保證了各個server之間的同步。全稱 Zookeeper Atomic Broadcast Protocol - Zookeeper 原子廣播協議。

兩種模式

Zab協議有兩種模式,它們分別是恢復模式廣播模式

廣播模式

廣播模式類似於分佈式事務中的 Two-phase commit (兩階段式提交),因爲Zookeeper中一次寫操作就是被當做一個事務,所以這實際上本質是相同的。

廣播模式,一次寫請求要經歷以下的步驟

  1. ZooKeeper Server接受到Client的寫請求
  2. 寫請求都被轉發給Leader節點
  3. Leader節點先將更新持久化到本地
  4. Leader節點將此次更新提議(propose)給Followers,進入收集選票的流程
  5. Follower節點接收請求,成功將修改持久化到本地,發送一個ACK給Leader
  6. Leader接收到半數以上的ACK時,Leader將廣播commit消息並在本地deliver該消息。
  7. 當收到Leader發來的commit消息時,Follower也會deliver該消息。

廣播協議在所有的通訊過程中使用TCP的FIFO信道,通過使用該信道,使保持有序性變得非常的容易。通過FIFO信道,消息被有序的deliver。只要收到的消息一被處理,其順序就會被保存下來。

但是這種模式下,如果Leader自身發生了故障,Zookeeper的集羣不就提供不了寫服務了嗎?這就引入了下面的恢復模式。

恢復模式

簡單點來說,當集羣中的Leader故障或者服務啓動的時候,ZAB就會進入恢復模式,其中包括Leader選舉和完成其他Server和Leader之間的狀態同步

NOTE:選主是ZAB協議中最爲重要和複雜的過程。這裏面的概念知識較多,放在本章一起講反而不利於理解本章的知識,所以我打算在下一章單獨介紹,同學們可以選擇性地食用。

關於Zookeeper 集羣的一些其他討論

1. Zookeeper(讀性能)可伸縮性 和 Observer節點

一個集羣的可伸縮性即可以引入更多的集羣節點,來提升某種性能。Zookeeper實際上就是提供讀服務和寫服務。在最早的時候,Zookeeper是通過引入Follower節點來提升讀服務的性能。但是根據我們之前學習過的讀寫機制和ZAB協議的內容,引入新的Follower節點,會造成Zookeeper 寫服務的下降,因爲Leader發起的投票是要半數以上的Follower節點響應纔會成功,你Follower多了,就增加了協議中投票過程的壓力,可能會拖慢整個投票響應的速度。結果就是,Follower節點增加,集羣的寫操作吞吐會下降

在這種情況下,Zookeeper 在3.3.3版本之後,在集羣架構中引入了Observer角色,和Follower唯一的區別的就是不參與投票不參與選主。這樣既提升了讀性能,又不會影響寫性能。

另外提一句,Zookeeper的寫性能是不能被擴展的,這也是他不適合當做服務註冊發現中心的一個原因之一,在服務發現和健康監測場景下,隨着服務規模的增大,無論是應用頻繁發佈時的服務註冊帶來的寫請求,還是刷毫秒級的服務健康狀態帶來的寫請求,都會Zookeeper帶來很大的寫壓力,因爲它本身的寫性能是無法擴展的。後文引的文章會詳細介紹。

2. Zookeeper 與 CAP 理論

分佈式領域中存在CAP理論:

  • C:Consistency,一致性,數據一致更新,所有數據變動都是同步的。
  • A:Availability,可用性,系統具有好的響應性能。
  • P:Partition tolerance,分區容錯性。以實際效果而言,分區相當於對通信的時限要求。系統如果不能在時限內達成數據一致性,就意味着發生了分區的情況,必須就當前操作在C和A之間做出選擇,也就是說無論任何消息丟失,系統都可用。
CAP 定理的含義 -- 阮一峯

該理論已被證明:任何分佈式系統只可同時滿足兩點,無法三者兼顧。 因此,將精力浪費在思考如何設計能滿足三者的完美系統上是愚鈍的,應該根據應用場景進行適當取捨。

根據我們前面學習過的讀寫機制和ZAB協議的內容,Zookeeper本質應該是一個偏向CP的分佈式系統。因爲廣播協議本質上是犧牲了系統的響應性能的。另外從它的以下幾個特點也可以看出。也就是在第一章最後提出的幾個特點。

① 順序一致性
從同一個客戶端發起的事務請求,最終將會嚴格按照其發起順序被應用到ZooKeeper中。

② 原子性
所有事務請求的結果在集羣中所有機器上的應用情況是一致的,也就是說要麼整個集羣所有集羣都成功應用了某一個事務,要麼都沒有應用,一定不會出現集羣中部分機器應用了該事務,而另外一部分沒有應用的情況。

③ 單一視圖
無論客戶端連接的是哪個ZooKeeper服務器,其看到的服務端數據模型都是一致的。

④ 可靠性
一旦服務端成功地應用了一個事務,並完成對客戶端的響應,那麼該事務所引起的服務端狀態變更將會被一直保留下來,除非有另一個事務又對其進行了變更。

3. Zookeeper 作爲 服務註冊中心的侷限性

直接引一篇阿里中間件的文章吧,講的比我好。實際在生產情況下,大多數公司沒有達到像大公司那樣的微服務量級,Zookeeper是完全能滿足服務註冊中心的需求的。

阿里巴巴爲什麼不用 ZooKeeper 做服務發現?

總結

本章主要介紹了Zookeeper的集羣架構,詳述了ZK的幾種角色和組件,還介紹了Zookeeper的讀寫機制和最核心的ZAB協議,最後對其他一些比較雜的知識點統一歸在一起討論了一下。

本章的知識我本人認爲信息量還是蠻大的,整理完之後我自己對Zookeeper集羣服務的機制原理有了更深的體會。閱讀時最好能夠結合第一章的一些基礎概念,這樣更有助於理解,讓知識點前後呼應。希望能對你理解Zookeeper起到幫助。

下一章我會詳細介紹本章未介紹的Zookeeper選主過程(Leader Election)。

參考

[1] <https://zookeeper.apache.org/... 官方文檔

[2] 阿里巴巴爲什麼不用 ZooKeeper 做服務發現?

[3] https://www.cnblogs.com/sundd...

[4] CAP 定理的含義 -- 阮一峯

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章