1. 程式人生 > >ZooKeeper學習第五期–ZooKeeper管理分散式環境中的資料

ZooKeeper學習第五期–ZooKeeper管理分散式環境中的資料

ZooKeeper學習第五期–ZooKeeper管理分散式環境中的資料

引言

本節本來是要介紹ZooKeeper的實現原理,但是ZooKeeper的原理比較複雜,它涉及到了paxos演算法、Zab協議、通訊協議等相關知識,理解起來比較抽象所以還需要藉助一些應用場景,來幫我們理解。由於內容比較多,一口氣吃不成胖子,得慢慢來一步一個腳印,因此我對後期ZooKeeper的學習規劃如下:

第一階段:

|—理解ZooKeeper的應用

    |—ZooKeeper是什麼

    |—ZooKeeper能幹什麼

    |—ZooKeeper 怎麼使用

第二階段:

|—理解ZooKeeper原理準備

    |—瞭解paxos

    |—理解 zab原理

    |—理解選舉/同步流程

第三階段:

    |—深入ZooKeeper原理

        |—分析原始碼

        |—嘗試開發分散式應用

由於內容較多,而且理解較為複雜,所以每個階段分開來學習和介紹,那麼本文主要介紹的的是第一階段,該階段一般應該放在前面介紹,但感覺像一些ZooKeeper應用案例,如果沒有一定的ZooKeeper基礎,理解起來也比較抽象, 所以放在這介紹。大家可以對比一下前面的應用程式,來對比理解一下前面的那些應用到底用到ZooKeeper的那些功能,來進一步理解ZooKeeper的實現理念,由於網上關於這方面的介紹比較多,如果一些可愛的博友對該內容已經比較瞭解,那麼您可以不用往下看了,繼續下一步學習。

一、ZooKeeper產生背景

1.1 分散式的發展

分散式這個概念我想大家並不陌生,但真正實戰開始還要從google說起,很早以前在實驗室中分散式被人提出,可是說是計算機內入行較為複雜學習較為困難的技術,並且市場也並不成熟,因此大規模的商業應用一直未成出現,但從Google 釋出了MapReduceDFS 以及Bigtable的論文之後,分散式在計算機界的格局就發生了變化,從架構上實現了分散式的難題,並且成熟的應用在了海量資料儲存計算上,其叢集的規模也是當前世界上最為龐大的。

以DFS 為基礎的分散式計算框架keyvalue 資料高效的解決運算的瓶頸,而且開發人員不用再寫複雜的分散式程式,只要底層框架完備開發人員只要用較少的程式碼就可以完成分散式程式的開發,這使得開發人員只需要關注業務邏輯的即可。Google 在業界技術上的領軍地位,讓業界望塵莫及的技術實力,IT 因此也是對Google 所退出的技術十分推崇。在最近幾年中分散式則是成為了海量資料儲存以及計算、高併發、高可靠性、高可用性的解決方案。

1.2 ZooKeeper的產生

眾所周知通常分散式架構都是中心化的設計,就是一個主控機連線多個處理節點。問題可以從這裡考慮,當主控機失效時,整個系統則就無法訪問了,所以保證系統的高可用性是非常關鍵之處,也就是要保證主控機的高可用性。分散式鎖就是一個解決該問題的較好方案,多主控機搶一把鎖。在這裡我們就涉及到了我們的重點Zookeeper。

ZooKeeper是什麼,chubby 我想大家都不會陌生的,chubby 是實現Google 的一個分散式鎖的實現,運用到了paxos 演算法解決的一個分散式事務管理的系統。Zookeeper 就是雅虎模仿強大的Google chubby 實現的一套分散式鎖管理系統。同時,Zookeeper 分散式服務框架是Apache Hadoop的一個子專案,它是一個針對大型分散式系統的可靠協調系統,它主要是用來解決分散式應用中經常遇到的一些資料管理問題,可以高可靠的維護元資料。提供的功能包括:配置維護、名字服務、分散式同步、組服務等。ZooKeeper的設計目標就是封裝好複雜易出錯的關鍵服務,將簡單易用的介面和效能高效、功能穩定的系統提供給使用者。

1.3 ZooKeeper的使用

Zookeeper 作為一個分散式的服務框架,主要用來解決分散式叢集中應用系統的一致性問題,它能提供基於類似於檔案系統的目錄節點樹方式的資料儲存但是 Zookeeper 並不是用來專門儲存資料的,它的作用主要是用來維護監控你儲存的資料的狀態變化。通過監控這些資料狀態的變化,從而可以達到基於資料的叢集管理,後面將 會詳細介紹 Zookeeper 能夠解決的一些典型問題。

注意一下這裡的”資料“是有限制的:

(1) 從資料大小來看:我們知道ZooKeeper的資料儲存在一個叫ReplicatedDataBase 的資料庫中,該資料是一個記憶體資料庫,既然是在記憶體當中,我就應該知道該資料量就應該不會太大,這一點上就與hadoop的HDFS有了很大的區別,HDFS的資料主要儲存在磁碟上,因此資料儲存主要是HDFS的事,而ZooKeeper主要是協調功能,並不是用來儲存資料的。

(2) 從資料型別來看:正如前面所說的,ZooKeeper的資料在記憶體中,由於記憶體空間的限制,那麼我們就不能在上面隨心所欲的儲存資料,所以ZooKeeper儲存的資料都是我們所關心的資料而且資料量還不能太大,而且還會根據我們要以實現的功能來選擇相應的資料。簡單來說,幹什麼事存什麼資料,ZooKeeper所實現的一切功能,都是由ZK節點的性質該節點所關聯的資料實現的,至於關聯什麼資料那就要看你幹什麼事了。

例如:

  ① 叢集管理:利用臨時節點特性,節點關聯的是機器的主機名、IP地址等相關資訊,叢集單點故障也屬於該範疇。

  ② 統一命名:主要利用節點的唯一性和目錄節點樹結構。

  ③ 配置管理:節點關聯的是配置資訊。

  ④ 分散式鎖:節點關聯的是要競爭的資源。

二、ZooKeeper應用場景

ZooKeeper是一個高可用的分散式資料管理與系統協調框架。基於對Paxos演算法的實現,使該框架保證了分散式環境中資料的強一致性,也正是基於這樣的特性,使得zookeeper能夠應用於很多場景。需要注意的是,ZK並不是生來就為這些場景設計,都是後來眾多開發者根據框架的特性,摸索出來的典型使用方法。因此,我們也可以根據自己的需要來設計相應的場景實現。正如前文所提到的,ZooKeeper 實現的任何功能都離不開ZooKeeper的資料結構,任何功能的實現都是利用”Znode結構特性+節點關聯的資料“來實現的,好吧那麼我們就看一下ZooKeeper資料結構有哪些特性。ZooKeeper資料結構如下圖所示:

圖2.1 ZooKeeper資料結構

Zookeeper 這種資料結構有如下這些特點:

每個子目錄項如 NameService 都被稱作為 znode,這個 znode 是被它所在的路徑唯一標識,如 Server1 這個 znode 的標識為 /NameService/Server1

znode 可以有子節點目錄,並且每個 znode 可以儲存資料,注意 EPHEMERAL 型別的目錄節點不能有子節點目錄;

znode 是有版本的,每個 znode 中儲存的資料可以有多個版本,也就是一個訪問路徑中可以儲存多份資料

znode 可以是臨時節點,一旦建立這個 znode 的客戶端與伺服器失去聯絡,這個 znode 也將自動刪除,Zookeeper 的客戶端和伺服器通訊採用長連線方式,每個客戶端和伺服器通過心跳來保持連線,這個連線狀態稱為 session,如果 znode 是臨時節點,這個 session 失效,znode 也就刪除了;

znode 的目錄名可以自動編號,如 App1 已經存在,再建立的話,將會自動命名為 App2;

znode 可以被監控,包括這個目錄節點中儲存的資料的修改,子節點目錄的變化等,一旦變化可以通知設定監控的客戶端,這個是 Zookeeper 的核心特性,Zookeeper 的很多功能都是基於這個特性實現的。

2.1資料釋出與訂閱

(1) 典型場景描述

釋出與訂閱即所謂的配置管理,顧名思義就是將資料釋出到ZK節點上,供訂閱者動態獲取資料,實現配置資訊的集中式管理和動態更新。例如全域性的配置資訊地址列表等就非常適合使用。集中式的配置管理在應用叢集中是非常常見的,一般商業公司內部都會實現一套集中的配置管理中心,應對不同的應用叢集對於共享各自配置的需求,並且在配置變更時能夠通知到叢集中的每一個機器。

(2) 應用

索引資訊和叢集中機器節點狀態存放在ZK的一些指定節點,供各個客戶端訂閱使用。

系統日誌(經過處理後的)儲存,這些日誌通常2-3天后被清除。

應用中用到的一些配置資訊集中管理,在應用啟動的時候主動來獲取一次,並且在節點上註冊一個Watcher,以後每次配置有更新,實時通知到應用,獲取最新配置資訊。

業務邏輯中需要用到的一些全域性變數,比如一些訊息中介軟體的訊息佇列通常有個offset,這個offset存放在zk上,這樣叢集中每個傳送者都能知道當前的傳送進度

系統中有些資訊需要動態獲取,並且還會存在人工手動去修改這個資訊。以前通常是暴露出介面,例如JMX介面,有了ZK後,只要將這些資訊存放到ZK節點上即可。

(3) 應用舉例

例如:同一個應用系統需要多臺 PC Server 執行,但是它們執行的應用系統的某些配置項是相同的,如果要修改這些相同的配置項,那麼就必須同時修改每臺執行這個應用系統的 PC Server,這樣非常麻煩而且容易出錯。將配置資訊儲存在 Zookeeper 的某個目錄節點中,然後將所有需要修改的應用機器監控配置資訊的狀態,一旦配置資訊發生變化,每臺應用機器就會收到 Zookeeper 的通知,然後從 Zookeeper 獲取新的配置資訊應用到系統中。ZooKeeper配置管理服務如下圖所示:

圖2.2 配置管理結構圖

Zookeeper很容易實現這種集中式的配置管理,比如將所需要的配置資訊放到/Configuration 節點上,叢集中所有機器一啟動就會通過Client/Configuration這個節點進行監控【zk.exist(“/Configuration″,true)】,並且實現Watcher回撥方法process(),那麼在zookeeper上/Configuration節點下資料發生變化的時候,每個機器都會收到通知,Watcher回撥方法將會被執行,那麼應用再取下資料即可【zk.getData(“/Configuration″,false,null)】。

2.2統一命名服務(Name Service)

(1) 場景描述

分散式應用中,通常需要有一套完整的命名規則,既能夠產生唯一的名稱又便於人識別和記住,通常情況下用樹形的名稱結構是一個理想的選擇,樹形的名稱結構是一個有層次的目錄結構,既對人友好又不會重複。說到這裡你可能想到了 JNDI,沒錯 Zookeeper 的 Name Service 與 JNDI 能夠完成的功能是差不多的,它們都是將有層次的目錄結構關聯到一定資源上,但是Zookeeper的Name Service 更加是廣泛意義上的關聯,也許你並不需要將名稱關聯到特定資源上,你可能只需要一個不會重複名稱,就像資料庫中產生一個唯一的數字主鍵一樣。

(2) 應用

在分散式系統中,通過使用命名服務,客戶端應用能夠根據指定的名字來獲取資源服務的地址提供者等資訊。被命名的實體通常可以是叢