一、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 服務對外就是可用的。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。 |
3.7.x |
基於Java控制ZooKeeper伺服器的API。 |
3.6.x |
效能和安全性方面帶來了許多改進。 |
3.5.x |
支援動態擴容/縮容。 |
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/