Zookeeper介紹與叢集安裝

TimeSay發表於2024-11-05

一、ZooKeeper 簡介

1.1 ZooKeeper 是什麼

zookeeper 是一個高效能的分散式應用程式協調服務,應用程式可以基於他非常簡單的實現同步服務、分組服務、配置維護、命名服務等,透過 zookeeper,你可以使用現成的元件實現一致性服務、分組管理、leader 選舉。 由於工程師不能很好地使用鎖機制,以及基於訊息的協調機制不適合在某些應用中使用,因此需要有一種可靠的、可擴充套件的、分散式的、可配置的協調機制來統一系統的狀態。Zookeeper 的目的就在於此。 zookeeper 十分易用,它使用和檔案系統中目錄樹相似的結構來實現他的功能,它使用 java 和 C 編寫,執行在 java 環境下。

1.2 ZooKeeper 角色

角色

描述

Leader

發起投票、決議,更新系統狀態

Follower

接收客戶端請求,向客戶端返回請求結果,選舉過程中參與投票

Observer

接收客戶端連線,向 Leader 轉發寫請求,同步 Leader 狀態,不參與投票,主要用於擴充套件系統,增加系統吞吐效能

Client

發起請求

ZooKeeper 引用了 Leader、Follower和 Observer 三個角色。ZooKeeper 叢集中的所有機器透過選舉的方式選出一個 Leader,Leader 可以為客戶端提供讀服務和寫服務。除了 Leader 外,叢集中還包括了 Follower 和 Observer 。Follower 和 Observer 都能夠提供讀服務,唯一區別在於,*Observer * 不參與 Leader 的選舉過程,也不參與寫操作的"過半寫成功"策略,因此 Observer 可以在不影響寫效能的情況下提升叢集的讀效能。

1.3 ZooKeeper 特性

原子性

在Zookeeper中要麼更新成功,要麼失敗,不存在只產生部分結果的情況。

高效能

Zookeeper的速度非常快。ZooKeeper 應用程式在數千臺機器上執行,尤其是在讀多寫少的情況下,它的效能最佳,比率約為 10:1。

高可靠

就像它協調的分散式應用程式一樣,ZooKeeper 的部署本身也是多節點的,其中有且僅有一個Leader節點,組成 ZooKeeper 叢集的伺服器之間相互保持瞭解,並且它們在永續性儲存中維護狀態的記憶體映像,以及事務日誌和快照資訊。

通常情況下,只要大多數伺服器可用,ZooKeeper 服務對外就是可用的。ZooKeeper 叢集中,建議部署奇數個 ZooKeeper節點(或程序) —— 大多數情況下,3個節點就足夠了。節點個數並不是越多越好 —— 節點越多,節點間通訊所需的時間就會越久,選舉 Leader 時需要的時間也會越久。

順序一致性

Zookeeper保證 來自客戶端的更新將按傳送順序處理。

ZooKeeper 在每次更新時都會使用一個數字來標記,該數字反映了所有 ZooKeeper 事務的順序。

1.4 資料模型和分層名稱空間

資料模型

ZooKeeper 提供的名稱空間與標準檔案系統的名稱空間非常相似。名稱是一系列由斜槓 (/) 分隔的路徑元素。ZooKeeper 名稱空間中的每個節點都有路徑標識。

分層名稱空間

zookeeper的分層名稱空間圖:

Zookeeper的資料儲存節點型別分為了持久節點、臨時節點、容器節點、TTL 節點。與標準檔案系統不同,ZooKeeper 名稱空間中的每個節點都可以有與之關聯的資料以及子節點。這就像有一個檔案系統,允許檔案也是一個目錄。我們使用官方術語 znode 來表示一個 ZooKeeper的 資料節點。

Znodes 維護一個統計資訊結構,其中包括資料更改、ACL 更改和時間戳的版本號,以允許快取驗證和協調更新。每當 znode 的資料發生變化時,版本號就會增加。例如,每當客戶端檢索資料時,它也會接收資料的版本。儲存在名稱空間中每個 znode 的資料都是以原子方式讀取和寫入的。讀取獲取與 znode 關聯的所有資料位元組,寫入替換所有資料。每個節點都有一個訪問控制列表 (ACL),用於限制誰可以執行哪些操作。

ZooKeeper 被設計用於儲存協調資料:狀態資訊、配置、位置資訊等,因此每個節點儲存的資料通常很小,在位元組到千位元組的範圍內。

znode的屬性說明:

ZooKeeper 樹中的每個節點都稱為 znode。透過bin/zkCli.sh start 連線上zk服務後,執行get -s znode_name,可以獲取znode(示例znode是zk)的屬性資訊,如下:

[zk: 127.0.0.1:2181(CONNECTED) 11] get -s /zk
my_data
cZxid = 0x2
ctime = Thu Dec 07 10:27:25 CST 2023
mZxid = 0x2
mtime = Thu Dec 07 10:27:25 CST 2023
pZxid = 0x2
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 7
numChildren = 0

其中:

  • my_data: 是該節點本身儲存的內容。
  • cZxid:該節點建立的事務id。
  • ctime:該節點建立時的時間。
  • mZxid:該節點被修改的事務id,即每次對znode的修改都會更新mZxid。
  • mtime:該節點最新一次更新發生時的時間。
  • pZxid:表示該節點的子節點列表最後一次修改的事務ID,新增子節點或刪除子節點就會影響子節點列表,但是修改子節點的資料內容則不影響該ID。
  • cversion:子節點的版本號。當該節點的子節點有變化時,cversion 的值就會增加1。
  • dataVersion:資料版本號,資料每次修改該版本號加1。
  • aclVersion:許可權版本號,許可權每次修改該版本號加1。
  • ephemeralOwner:如果該節點為臨時節點, ephemeralOwner值表示與該節點繫結的session id. 如果不是, ephemeralOwner值為0x0。
  • dataLength:該節點的資料長度。
  • numChildren:該節點擁有子節點的數量。

Zookeeper裡面的版本號和我們理解的版本號不同,它表示的是對資料節點的內容、子節點列表或者ACL資訊的修改次數。節點建立時dataversion、aclversion,cversion都為0,每次修改響應內容其對應的版本號加1。

Zookeeper中的版本號其實就是樂觀鎖的一種思想。兩個API操作可以有條件地執行:setData和delete。這兩個呼叫以版本號作為轉入引數,只有當轉入引數的版本號與伺服器上的版本號一致時呼叫才會成功。當多個Zookeeper客戶端對同一個znode進行操作時,版本的作用就會顯得尤為重要。

1.5 watches

zooKeeper支援watch的概念。客戶可以在znode上設定watch。當znode發生變化時,手錶將被觸發並移除。當watch被觸發時,客戶端會收到一個資料包,說明znode已更改。如果客戶端和ZooKeeper伺服器之一之間的連線中斷,客戶端將收到本地通知。
3.6.0中的新功能:客戶端還可以在znode上設定永久的遞迴監視,這些監視在觸發時不會被刪除,並且會遞迴地觸發註冊的znode以及任何子znode上的更改。保證ZooKeeper非常快速和簡單。然而,由於其目標是為構建更復雜的服務(如同步)奠定基礎,因此它提供了一套保證:

  • 順序一致性-客戶端的更新將按傳送順序應用。
  • 原子性-更新成功或失敗。沒有部分結果。
  • 單一系統映像-無論客戶端連線到哪個伺服器,客戶端都會看到相同的服務檢視。也就是說,即使客戶端故障轉移到具有相同會話的其他伺服器,客戶端也永遠不會看到系統的舊檢視。
  • 可靠性-一旦應用了更新,它將從那時起一直持續到客戶端覆蓋更新為止。
  • 及時性-保證系統的客戶端檢視在一定時間內保持最新。

簡單API:

  • ZooKeeper的設計目標之一是提供一個非常簡單的程式設計介面。因此,它只支援以下操作:
  • create:在樹中的某個位置建立節點
  • delete:刪除節點
  • exists:測試某個位置是否存在節點
  • get data:從節點讀取資料
  • set data:將資料寫入節點
  • get children:檢索節點的子節點列表
  • sync:等待資料傳播

1.6 Implementation

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

複製資料庫是一個包含整個資料樹的記憶體資料庫。更新會記錄到磁碟以實現可恢復性,寫入操作在應用於記憶體資料庫之前會序列化到磁碟。

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

作為協議協議的一部分,來自客戶端的所有寫入請求都被轉發到一個稱為leader的伺服器。其餘的ZooKeeper伺服器,稱為追隨者,從領導者那裡接收訊息建議,並就訊息傳遞達成一致。訊息傳遞層負責在失敗時替換領導者,並將追隨者與領導者同步。

ZooKeeper使用自定義原子訊息傳遞協議。由於訊息傳遞層是原子的,ZooKeeper可以保證本地副本永遠不會發散。當leader收到寫入請求時,它會計算應用寫入時系統的狀態,並將其轉換為捕獲此新狀態的事務。

1.7 版本差異

版本 內容
3.9x 用於拍攝快照和流出資料的管理伺服器 API
傳達觸發 WatchEvent 觸發的 Zxid
TLS - 客戶端信任/金鑰儲存的動態載入
新增 Netty-TcNative OpenSSL 支援
向 Zktreeutil 新增 SSL 支援
提高 syncRequestProcessor 效能
更新所有第三方依賴項,以消除所有已知的 CVE。
3.8.x

日誌框架從Apache Log4j1遷移到LogBack。
從檔案讀取金鑰/信任儲存密碼。
恢復對OSGI的支援。
降低了Prometheus指標對效能的影響。
JDK17官方支援。
更新所有第三方依賴關係,以消除所有已知的CVE。

3.7.x

基於Java控制ZooKeeper伺服器的API。
支援BCFKS金鑰/信任儲存格式。
支援可多個SASL身份驗證的超級使用者。
“whoami”API和CLI命令。
對受限請求進行加速處理。
C和Perl客戶端中的SASL支援。
禁用雜湊身份驗證的可能性。

3.6.x

效能和安全性方面帶來了許多改進。
客戶端引入了新的API。
允許Followers 託管Observers。
ZooKeeper內建資料一致性檢查。
快照新增根據日誌大小配置。

3.5.x

支援動態擴容/縮容。
新節點型別:容器、TTL。
原子廣播協議的SSL支援。
升級到Netty 4.1。
專案Maven構建。
各種效能和穩定性改進。
建議的最低JDK版本現在是1.8。

3.4.x及以下

基礎功能、客戶端、選舉演算法等功能實現與完善。

1.8 配置:

https://zookeeper.apache.org/doc/r3.9.3/zookeeperAdmin.html#sc_systemReq

二、ZooKeeper 叢集搭建

一、 安裝jdk

此處省略

二、 安裝zookeeper

2.1 下載原始碼包,並解壓

官網下載地址:http://www.apache.org/dyn/closer.cgi/zookeeper

wget http://mirror.olnevhost.net/pub/apache/zookeeper/zookeeper-3.5.9/apache-zookeeper-3.5.9-bin.tar.gz
tar zxvf apache-zookeeper-3.5.9-bin.tar.gz
mv apache-zookeeper-3.5.9-bin /usr/local/zookeeper

2.2 修改環境變數

編輯 /etc/profile 檔案, 在檔案末尾新增以下環境變數配置:

# ZooKeeper Env
export ZOOKEEPER_HOME=/usr/local/zookeeper
export PATH=$PATH:$ZOOKEEPER_HOME/bin

執行以下命令使環境變數生效: source /etc/profile

2.3 重新命名配置檔案

初次使用 ZooKeeper 時,需要將$ZOOKEEPER_HOME/conf 目錄下的 zoo_sample.cfg 重新命名為 zoo.cfg, zoo.cfg

mv  $ZOOKEEPER_HOME/conf/zoo_sample.cfg $ZOOKEEPER_HOME/conf/zoo.cfg

2.4 單機模式--修改配置檔案

建立目錄/usr/local/zookeeper/data/usr/local/zookeeper/logs 修改配置檔案

tickTime=2000
initLimit=10
syncLimit=5
dataDir=/usr/local/zookeeper/data
dataLogDir=/usr/local/zookeeper/logs
clientPort=2181

如果是多節點,配置檔案中尾部增加

server.1=192.168.1.1:2888:3888 #如果偽叢集搭建 IP可相同,埠可不同
server.2=192.168.1.2:2888:3888
server.3=192.168.1.3:2888:3888

同時,增加

#master
echo "1">/usr/local/zookeeper/data/myid

#slave1
echo "2">/usr/local/zookeeper/data/myid

#slave2
echo "3">/usr/local/zookeeper/data/myid

2.5 啟動 ZooKeeper 服務

# cd /usr/local/zookeeper/zookeeper-3.4.11/bin
# ./zkServer.sh  start
ZooKeeper JMX enabled by default
Using config: /usr/local/zookeeper/zookeeper-3.4.11/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED

zkServer.sh  status
ZooKeeper JMX enabled by default
Using config: /usr/local/zookeeper/bin/../conf/zoo.cfg
Mode: follower

2.6 驗證zooKeeper服務

服務啟動完成後,可以使用 telnet 和 stat 命令驗證伺服器啟動是否正常:

# telnet 127.0.0.1 2181
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
stat
Zookeeper version: 3.4.11-37e277162d567b55a07d1755f0b31c32e93c01a0, built on 11/01/2017 18:06 GMT
Clients:
/127.0.0.1:48430[0](queued=0,recved=1,sent=0)

Latency min/avg/max: 0/0/0
Received: 1
Sent: 0
Connections: 1
Outstanding: 0
Zxid: 0x0
Mode: standalone
Node count: 4
Connection closed by foreign host.

2.7 停止 ZooKeeper 服務

想要停止 ZooKeeper 服務, 可以使用如下命令:

# cd /usr/local/zookeeper/zookeeper-3.4.11/bin
# ./zkServer.sh  stop
ZooKeeper JMX enabled by default
Using config: /usr/local/zookeeper/zookeeper-3.4.11/bin/../conf/zoo.cfg
Stopping zookeeper ... STOPPED

三、zk ui安裝 (選裝,頁面檢視zk的資料)

拉取程式碼

#git clone https://github.com/DeemOpen/zkui.git

原始碼編譯需要安裝 maven

# wget http://repos.fedorapeople.org/repos/dchen/apache-maven/epel-apache-maven.repo -O /etc/yum.repos.d/epel-apache-maven.repo
#cd zkui/
#yum install -y maven
#mvn clean install

修改配置檔案預設值

#vim config.cfg
serverPort=9090     #指定埠
zkServer=192.168.1.1:2181
sessionTimeout=300000

啟動程式至後臺

2.0-SNAPSHOT 會隨軟體的更新版本不同而不同,執行時請檢視target 目錄中真正生成的版本

 nohup java -jar target/zkui-2.0-SNAPSHOT-jar-with-dependencies.jar & 

用瀏覽器訪問:

http://192.168.1.1:9090/

相關文章