簡要分析ZooKeeper基本原理及安裝部署

徐劉根發表於2019-05-27

一、ZooKeeper 基本概念

1、ZooKeeper 是什麼?

Zookeeper官網地址: zookeeper.apache.org/

Zookeeper官網文件地址:zookeeper.apache.org/doc/trunk/i…

ZooKeeper 是Hadoop下的一個子專案,它是一個針對大型分散式系統的可靠協調系統;它提供的功能包括:配置維護、名字服務、分散式同步、組服務等; 它的目標就是封裝好複雜易出錯的關鍵服務,將簡單易用的介面和效能高效、功能穩定的系統提供給使用者。

Zookeeper一個最常用的使用場景就是用於擔任服務生產者和服務消費者的註冊中心,服務生產者將自己提供的服務註冊到Zookeeper中心,服務的消費者在進行服務呼叫的時候先到Zookeeper中查詢服務,獲取到服務生產者的詳細資訊之後,再去呼叫服務生產者的內容與資料,簡單示例圖如下:

這裡寫圖片描述

2、ZooKeeper設計目標:

ZooKeeper允許分散式程式通過共享的層次結構名稱空間進行相互協調,這與標準檔案系統類似。 名稱空間由ZooKeeper中的資料暫存器組成 - 稱為znode,這些類似於檔案和目錄。 與為儲存設計的典型檔案系統不同,ZooKeeper資料儲存在記憶體中,這意味著ZooKeeper可以實現高吞吐量和低延遲。

Zookeeper層次結構名稱空間示意圖如下:

這裡寫圖片描述

通過這種樹圖結構的資料模型,很容易的查詢到具體的某一個服務。

3、ZooKeeper主要特點:

1)、最終一致性:為客戶端展示同一檢視,這是 ZooKeeper 最重要的效能。
2)、可靠性:如果訊息被一臺伺服器接受,那麼它將被所有的伺服器接受。
3)、實時性:ZooKeeper 不能保證兩個客戶端同時得到剛更新的資料,如果需要最新資料,應該在讀資料之前呼叫sync()介面。
4)、等待無關(wait-free):慢的或者失效的 client 不干預快速的client的請求。
5)、原子性:更新只能成功或者失敗,沒有中間其它狀態。
6)、順序性:對於所有Server,同一訊息釋出順序一致。
複製程式碼

二、ZooKeeper 基本原理

1、ZooKeeper 系統架構

首先看一下 ZooKeeper 的架構圖。

這裡寫圖片描述

ZooKeeper 的架構圖中我們需要了解和掌握的主要有:

(1)ZooKeeper分為***伺服器端(Server)*** 和***客戶端(Client)***,客戶端可以連線到整個 ZooKeeper服務的任意伺服器上(除非 leaderServes 引數被顯式設定, leader 不允許接受客戶端連線)。

(2)客戶端使用並維護一個 TCP 連線,通過這個連線傳送請求、接受響應、獲取觀察的事件以及傳送心跳。如果這個 TCP 連線中斷,客戶端將自動嘗試連線到另外的 ZooKeeper伺服器。客戶端第一次連線到 ZooKeeper服務時,接受這個連線的 ZooKeeper伺服器會為這個客戶端建立一個會話。當這個客戶端連線到另外的伺服器時,這個會話會被新的伺服器重新建立。

(3)上圖中每一個Server代表一個安裝Zookeeper服務的機器,即是整個提供Zookeeper服務的叢集(或者是由偽叢集組成);

(4)組成ZooKeeper服務的伺服器必須彼此瞭解。 它們維護一個記憶體中的狀態影象,以及持久儲存中的事務日誌和快照, 只要大多數伺服器可用,ZooKeeper服務就可用;

(5)ZooKeeper 啟動時,將從例項中選舉一個 leader,Leader 負責處理資料更新等操作,一個更新操作成功的標誌是當且僅當大多數Server在記憶體中成功修改資料。每個Server 在記憶體中儲存了一份資料。

(6)Zookeeper是可以叢集複製的,叢集間通過Zab協議(Zookeeper Atomic Broadcast)來保持資料的一致性;

(7)Zab協議包含兩個階段:leader election階段***和***Atomic Brodcast階段

  • a) 叢集中將選舉出一個leader,其他的機器則稱為follower,所有的寫操作都被傳送給leader,並通過brodcast將所有的更新告訴給follower。
  • b) 當leader崩潰或者leader失去大多數的follower時,需要重新選舉出一個新的leader,讓所有的伺服器都恢復到一個正確的狀態。
  • c) 當leader被選舉出來,且大多數伺服器完成了 和leader的狀態同步後,leadder election 的過程就結束了,就將會進入到Atomic brodcast的過程。
  • d) Atomic Brodcast同步leader和follower之間的資訊,保證leader和follower具有形同的系統狀態。

2、Zookeeper 角色

啟動 Zookeeper 伺服器叢集環境後,多個 Zookeeper 伺服器在工作前會選舉出一個 Leader。選舉出 leader 前,所有 server 不區分角色,都需要平等參與投票( obServer 除外,不參與投票);

選主過程完成後,存在以下幾種角色:

這裡寫圖片描述

思考:

1、為什麼需要server?

①ZooKeeper 需保證高可用和強一致性;
②為了支援更多的客戶端,需要增加更多的Server;
③Follower增多會導致投票階段延遲增大,影響效能。 
複製程式碼

2、在Zookeeper 中ObServer 起到什麼作用?

①ObServer 不參與投票過程,只同步 leader的狀態 ;
②Observers 接受客戶端的連線,並將寫請求轉發給 leader節點 ;
③加入更多ObServer 節點,提高伸縮性,同時還不影響吞吐率。
複製程式碼

3、為什麼在Zookeeper中Server 數目一般為奇數?

我們知道在Zookeeper中 Leader 選舉演算法採用了Paxos協議。Paxos核心思想是當多數 Server 寫成功,則任務資料寫成功。 
①如果有3個Server,則最多允許1個Server 掛掉。 
②如果有4個Server,則同樣最多允許1個Server掛掉。 
既然3個或者4個Server,同樣最多允許1個Server掛掉,那麼它們的可靠性是一樣的,所以選擇奇數個ZooKeeper Server即可,這裡選擇3個Server。
複製程式碼

3、ZooKeeper 寫資料流程

ZooKeeper 寫資料的流程圖如下所示。

這裡寫圖片描述

ZooKeeper 的寫資料流程主要分為以下幾步:

  • a)、比如 Client 向 ZooKeeper 的 Server1 上寫資料,傳送一個寫請求。

  • b)、如果Server1不是Leader,那麼Server1 會把接受到的請求進一步轉發給Leader,因為每個ZooKeeper的Server裡面有一個是Leader。這個Leader 會將寫請求廣播給各個Server,比如Server1和Server2, 各個Server寫成功後就會通知Leader。

  • c)、當Leader收到大多數 Server 資料寫成功了,那麼就說明資料寫成功了。如果這裡三個節點的話,只要有兩個節點資料寫成功了,那麼就認為資料寫成功了。寫成功之後,Leader會告訴Server1資料寫成功了。

  • d)、Server1會進一步通知 Client 資料寫成功了,這時就認為整個寫操作成功。

4、ZooKeeper 元件

ZooKeeper元件顯示了ZooKeeper服務的高階元件。 除了請求處理器,組成ZooKeeper服務的每個伺服器複製其自己的每個元件的副本。

這裡寫圖片描述

Replicated Database是包含整個資料樹的記憶體資料庫。 更新操作會記錄到磁碟裡以進行可恢復性,並且寫操作將在放到記憶體資料庫之前序列化到磁碟。

每個ZooKeeper伺服器服務客戶端。 客戶端連線到一個伺服器以提交irequest。 讀取請求從每個伺服器資料庫的本地副本服務。 更改服務狀態(寫入請求)的請求由協議進行處理。

作為協議協議的一部分,來自客戶端的所有寫請求被轉發到單個伺服器,稱為leader。 其餘的ZooKeeper伺服器(稱為followers)從領導者接收訊息提議並同意訊息傳遞。 訊息層負責在失敗時替換領導者,並與leader同步followers。

三、ZooKeeper 應用場景總結

1、統一命名服務

統一命名服務的命名結構圖如下所示:

這裡寫圖片描述
  1、在分散式環境下,經常需要對應用/服務進行統一命名,便於識別不同服務。   a)類似於域名與ip之間對應關係,ip不容易記住,而域名容易記住。   b)通過名稱來獲取資源或服務的地址,提供者等資訊。   2、按照層次結構組織服務/應用名稱。   a)可將服務名稱以及地址資訊寫到ZooKeeper上,客戶端通過ZooKeeper獲取可用服務列表類。

2、配置管理

配置管理結構圖如下所示:

這裡寫圖片描述

1、分散式環境下,配置檔案管理和同步是一個常見問題。   a)一個叢集中,所有節點的配置資訊是一致的,比如 Hadoop 叢集。   b)對配置檔案修改後,希望能夠快速同步到各個節點上。    2、配置管理可交由ZooKeeper實現。   a)可將配置資訊寫入ZooKeeper上的一個Znode。   b)各個節點監聽這個Znode。   c)一旦Znode中的資料被修改,ZooKeeper將通知各個節點。

3、叢集管理

叢集管理結構圖如下所示:

這裡寫圖片描述

1、分散式環境中,實時掌握每個節點的狀態是必要的。   a)可根據節點實時狀態做出一些調整。    2、可交由ZooKeeper實現。   a)可將節點資訊寫入ZooKeeper上的一個Znode。   b)監聽這個Znode可獲取它的實時狀態變化。    3、典型應用   a)HBase中Master狀態監控與選舉。

4、分散式通知與協調

1、分散式環境中,經常存在一個服務需要知道它所管理的子服務的狀態。   a)NameNode需知道各個Datanode的狀態。   b)JobTracker需知道各個TaskTracker的狀態。    2、心跳檢測機制可通過ZooKeeper來實現。

3、資訊推送可由ZooKeeper來實現,ZooKeeper相當於一個釋出/訂閱系統。

5、分散式鎖

處於不同節點上不同的服務,它們可能需要順序的訪問一些資源,這裡需要一把分散式的鎖。

分散式鎖具有以下特性:

1、ZooKeeper是強一致的。比如各個節點上執行一個ZooKeeper客戶端,它們同時建立相同的Znode,但是隻有一個客戶端建立成功。

2、實現鎖的獨佔性。建立Znode成功的那個客戶端才能得到鎖,其它客戶端只能等待。當前客戶端用完這個鎖後,會刪除這個Znode,其它客戶端再嘗試建立Znode,獲取分散式鎖。

3、控制鎖的時序。各個客戶端在某個Znode下建立臨時Znode,這個型別必須為CreateMode.EPHEMERAL_SEQUENTIAL,這樣該Znode可掌握全域性訪問時序。
複製程式碼

6、分散式佇列

分散式佇列分為兩種:

1、當一個佇列的成員都聚齊時,這個佇列才可用,否則一直等待所有成員到達,這種是同步佇列。   a)一個job由多個task組成,只有所有任務完成後,job才執行完成。   b)可為job建立一個/job目錄,然後在該目錄下,為每個完成的task建立一個臨時的Znode,一旦臨時節點數目達到task總數,則表明job執行完成。    2、佇列按照FIFO方式進行入隊和出隊操作,例如實現生產者和消費者模型。

三、ZooKeeper 安裝部署

zookeeper 的安裝模式有三種:

  • 單機模式( stand-alone):單機單 server;
  • 叢集模式:多機多 server,形成叢集;
  • 偽叢集模式:單機多個 server,形成偽叢集;

環境:Cent OS 7.0

1、單機模式

(1)根據需要建立目錄,例如我的目錄是:/home/xuliugen/Desktop/zookeeper-install

這裡寫圖片描述

(2)進入目錄,使用wget下載zookeeper, 下載地址:mirrors.tuna.tsinghua.edu.cn/apache/zook…

其他版本下載地址:mirrors.tuna.tsinghua.edu.cn/apache/zook…

完成如下:

這裡寫圖片描述

(3)使用: tar -xvf zookeeper-3.4.6.tar.gz 解壓縮該檔案;

(4)建立Zookeeper配置檔案:

在Zookeeper的安裝目錄下的conf檔案下,預設為:

這裡寫圖片描述

使用:cp zoo_sample.cfg zoo.cfg 命令,複製一份為zoo.cfg檔案,這是因為Zookeeper再啟動的時候預設使用的是zoo.cfg這個配置檔案。

(5)根據需求修改配置檔案內容:

一般預設的配置檔案就可以演示啟動,配置檔案如下:

# Zookeeper服務心跳檢測時間,單位為ms
tickTime=2000

# 投票選舉新leader的初始化時間
initLimit=10

# leader與follower心跳檢測最大容忍時間,響應超過syncLimit*tickTime,
# leader認為follower死掉,從伺服器列表中刪除該follower
syncLimit=5

# the directory where the snapshot is stored.
# do not use /tmp for storage, /tmp here is just
# example sakes.
dataDir=/tmp/zookeeper

# the port at which the clients will connect
clientPort=2181

# the maximum number of client connections.
# increase this if you need to handle more clients
#maxClientCnxns=60

# The number of snapshots to retain in dataDir
#autopurge.snapRetainCount=3

# Purge task interval in hours
# Set to "0" to disable auto purge feature
#autopurge.purgeInterval=1

複製程式碼

小提示:

在Zookeeper官方文件中給了一個關於效能優化的小經驗,就是有幾個其他配置引數可以大大提高效能:

為了獲得更新時的低延遲,重要的是有一個專用的事務日誌目錄。 預設情況下,事務日誌與資料快照和myid檔案放在同一目錄中。 dataLogDir引數指示用於事務日誌的不同目錄。
複製程式碼

意思就是說,最好將屬具目錄和日誌目錄分離開來,從而提高資料的讀取更新效率。

(6)啟動Zookeeper

在Zookeeper安裝目錄的bin目錄下:

這裡寫圖片描述

使用命令:./zkServer.sh start 即可開啟服務:

這裡寫圖片描述

使用: ./zkCli.sh 命令可以進入到命令列管理介面:

這裡寫圖片描述

到此單機模式就安裝結束了!

2、叢集模式 3、偽叢集模式

關於叢集模式 和偽叢集模式的配置,網上已經有很多內容,這裡不再演示,請移步檢視:

www.open-open.com/lib/view/op…

附錄:

zoo.cfg配置引數解釋:

這裡寫圖片描述


參考文章:

1、《大型分散式網站架構-設計與實踐 陳康賢-著》 2、《Zookeeper-3.3.5原始碼分析 劉少偉》 3、m.blog.csdn.net/article/det… 4、mt.sohu.com/20160527/n4… 5、www.open-open.com/lib/view/op…

搜尋或掃描下述二維碼關注微信公眾號:Java後端技術(ID: JavaITWork),和20萬人一起學Java!

Java後端技術專注Java相關技術:SSM、Spring全家桶、微服務、MySQL、MyCat、叢集、分散式、中介軟體、Linux、網路、多執行緒,偶爾講點運維Jenkins、Nexus、Docker、ELK,偶爾分享些技術乾貨,致力於Java全棧開發!

在這裡插入圖片描述

【視訊福利】2T免費學習視訊,搜尋或掃描上述二維碼關注微信公眾號:Java後端技術(ID: JavaITWork)回覆:1024,即可免費獲取!內含SSM、Spring全家桶、微服務、MySQL、MyCat、叢集、分散式、中介軟體、Linux、網路、多執行緒,Jenkins、Nexus、Docker、ELK等等免費學習視訊,持續更新!

相關文章