1 zookerper介紹
zookeeper是一個開源的分布式協調服務,由Apache軟件基金會提供,主要用于解決分布式應用中的數據管理、狀態同步和集群協調等問題。通過提供一個高性能、高可用的協調服務,幫助構建可靠的分布式系統。
Zookeeper的特點和功能:
- 數據模型:Zookeeper的數據模型類似于Unix文件系統,采用層次化的樹形結構,稱為Znode。每個Znode可以存儲數據和子節點,支持臨時節點和持久節點
- 一致性保證:Zookeeper保證了順序一致性、原子性、單一系統映像、實時性和持久性
- 核心功能:包括領導者選舉、分布式鎖、配置管理、服務注冊與發現等
Zookeeper的工作原理:
Zookeeper采用Leader-Follower架構,集群通常由奇數個節點組成,以確保在網絡分區或節點故障時仍能實現一致性與可用性。核心機制是ZAB協議(Zookeeper Atomic Broadcast),一種崩潰恢復的原子廣播協議,保證了在網絡分區和崩潰時的最終一致性和持久性
Zookeeper的應用場景:
-
Leader選舉:在分布式系統中,協調多個節點選出一個領導者是關鍵操作,例如Hadoop HDFS使用Zookeeper進行Namenode的故障轉移和選舉
-
分布式鎖:實現資源競爭的控制,Zookeeper提供了強大的分布式鎖功能
-
配置管理:保持配置的一致性和動態更新,例如Apache Storm使用Zookeeper來協調任務拓撲和節點狀態。
-
服務注冊與發現:Zookeeper常作為服務注冊中心,允許服務提供者注冊其服務,消費者動態發現服務
配置中心簡單理解:
假設多個應用有自己的配置文件,如果經常變更的話,修改起來比較麻煩;就可以使用配置中心統一存儲配置,讓應用程序去配置中心獲取配置
注冊中心簡單理解:
酒店商家到飛旅平臺 注冊,消費者在平臺上查看酒店信息。酒店平臺就是注冊中心供商家注冊
2 zookerper集群部署
2.1 部署zookerper集群
主機 | IP地址 |
---|---|
elk91 | 10.0.0.0.91 |
elk92 | 10.0.0.0.92 |
elk93 | 10.0.0.0.93 |
端口規劃:
- 2181:供客戶端訪問的端口
- 5888:zookerper數據同步和交換
- 6888:leader選舉
1.下載地址:https://dlcdn.apache.org/zookeeper/zookeeper-3.8.4/apache-zookeeper-3.8.4-bin.tar.gz
2.所有節點創建zookerper相關目錄,添加hosts文件解析
[root@elk91 ~]# mkdir -pv /zhiyong18/{softwares,data,logs}/[root@elk91 ~]# cat >> /etc/hosts <<EOF
10.0.0.91 elk91
10.0.0.92 elk92
10.0.0.93 elk93
EOF
3.配置elk91節點免密登錄其他節點
ssh-keygen -t rsa -f ~/.ssh/id_rsa -P '' -qssh-copy-id elk91
ssh-copy-id elk92
ssh-copy-id elk93
4.解壓軟件包,拷貝配置文件
[root@elk91 ~]# tar xvf apache-zookeeper-3.8.4-bin.tar.gz -C /zhiyong18/softwares/[root@elk91 ~]# cp /zhiyong18/softwares/apache-zookeeper-3.8.4-bin/conf/zoo{_sample.cfg,.cfg}[root@elk91 ~]# ll /zhiyong18/softwares/apache-zookeeper-3.8.4-bin/conf/zoo*
/zhiyong18/softwares/apache-zookeeper-3.8.4-bin/conf/zoo.cfg
/zhiyong18/softwares/apache-zookeeper-3.8.4-bin/conf/zoo_sample.cfg
5.修改zookeeper的配置文件,指定數據目錄、集群主機。然后同步配置文件到其他節點
cat > /zhiyong18/softwares/apache-zookeeper-3.8.4-bin/conf/zoo.cfg <<EOF
# 定義最小單元的時間范圍tick。
tickTime=2000
# 啟動時最長等待tick數量。
initLimit=5
# 數據同步時最長等待的tick時間進行響應ACK
syncLimit=2
# 指定數據目錄
dataDir=/zhiyong18/data/zk
# 監聽端口
clientPort=2181
# 開啟四字命令允許所有的節點訪問。
4lw.commands.whitelist=*server.91=10.0.0.91:5888:6888
server.92=10.0.0.92:5888:6888
server.93=10.0.0.93:5888:6888# # 監控相關
## Metrics Providers
# https://prometheus.io Metrics Exporter
#metricsProvider.className=org.apache.zookeeper.metrics.prometheus.PrometheusMetricsProvider
#metricsProvider.httpHost=0.0.0.0
#metricsProvider.httpPort=7000
#metricsProvider.exportJvmInfo=true
EOF
scp -r /zhiyong18/softwares/apache-zookeeper-3.8.4-bin/ 10.0.0.92:/zhiyong18/softwares/
scp -r /zhiyong18/softwares/apache-zookeeper-3.8.4-bin/ 10.0.0.93:/zhiyong18/softwares/
6.準備myID文件,ID必須和配置文件中的一樣
for ((host_id=91; host_id<=93; host_id++)); dossh elk${host_id} "mkdir /zhiyong18/data/zkecho ${host_id} > /zhiyong18/data/zk/myid"
done
7.編寫啟動腳本并傳輸到其他節點,最后啟動zookerper集群
cat > /lib/systemd/system/zk.service <<EOF
[Unit]
Description=zhiyong18 zookeeper server
After=network.target[Service]
Type=forking
Environment=JAVA_HOME=/usr/share/elasticsearch/jdk
ExecStart=/zhiyong18/softwares/apache-zookeeper-3.8.4-bin/bin/zkServer.sh start [Install]
WantedBy=multi-user.target
EOF
scp /lib/systemd/system/zk.service elk92:/lib/systemd/system/
scp /lib/systemd/system/zk.service elk93:/lib/systemd/system/
systemctl daemon-reload
systemctl enable --now zk
systemctl status zk
8.檢查各端口是否監聽
[root@elk92~]# ss -ntl | grep 2181
LISTEN 0 50 *:2181 *:*
9.配置環境變量,便于直接使用zookerper的變量進行操作
cat > /etc/profile.d/zk.sh <<EOF
#!/bin/bash
export JAVA_HOME=/usr/share/elasticsearch/jdk
export ZK_HOME=/zhiyong18/softwares/apache-zookeeper-3.8.4-bin
export PATH=$PATH:$ZK_HOME/bin:$JAVA_HOME/bin
EOF
scp /etc/profile.d/zk.sh elk92:/etc/profile.d
scp /etc/profile.d/zk.sh elk93:/etc/profile.dsource /etc/profile.d/zk.sh
10.連接zookeeper集群
[root@elk91 ~]# zkCli.sh -server 10.0.0.91:2181,10.0.0.92:2181,10.0.0.93:2181
...
[zk: 10.0.0.91:2181,10.0.0.92:2181,10.0.0.93:2181(CONNECTED) 0] ls /
[zookeeper]
[zk: 10.0.0.91:2181,10.0.0.92:2181,10.0.0.93:2181(CONNECTED) 1]
11.查看zookeeper集群的狀態。有2個是follower,1個是leader
zkServer.sh status
2.2 zookerper變量
設置占用的內存容量
[root@elk91 ~]# grep ^ZK_SERVER_HEAP /zhiyong18/softwares/apache-zookeeper-3.8.4-bin/bin/zkEnv.sh
ZK_SERVER_HEAP="${ZK_SERVER_HEAP:-128}"
2.2 圖形化連接工具zk-web
使用方式:java -jar jar包名
注意不要超過 jdk1.8
訪問地址:http://10.0.0.91:8099/
2.2 zookerper四字監控
zookeeper的四字監控命令
echo srvr | nc 10.0.0.93 2181
echo ruok | nc 10.0.0.93 2181
echo conf | nc 10.0.0.93 2181
3 zookerper常用命令增刪改查
連接集群:zkCli.sh -server 10.0.0.91:2181,10.0.0.92:2181,10.0.0.93:2181
1.查看zookeeper node列表
[zk: 10.0.0.93:2181(CONNECTED) 1] ls /
[zookeeper]
[zk: 10.0.0.93:2181(CONNECTED) 2]
2.創建zookeeper node并存儲數據
[zk: 10.0.0.91:2181,10.0.0.92:2181,10.0.0.93:2181(CONNECTED) 2] create /wzy666 xixi
Created /wzy666
[zk: 10.0.0.91:2181,10.0.0.92:2181,10.0.0.93:2181(CONNECTED) 3] get /wzy666
xixi
3.創建zookeeper node不存儲數據
[zk: 10.0.0.91:2181,10.0.0.92:2181,10.0.0.93:2181(CONNECTED) 4] create /wzy666/wzy999
Created /wzy666/wzy999[zk: 10.0.0.91:2181,10.0.0.92:2181,10.0.0.93:2181(CONNECTED) 6] get /wzy666/wzy999
null
4.修改zookeeper node的數據
[zk: 10.0.0.91:2181,10.0.0.92:2181,10.0.0.93:2181(CONNECTED) 7] set /wzy666/wzy999 999
[zk: 10.0.0.91:2181,10.0.0.92:2181,10.0.0.93:2181(CONNECTED) 8] get /wzy666/wzy999
999
5.刪除zookeeper node(必須為空,換句話說,沒有子目錄)
[zk: 10.0.0.91:2181,10.0.0.92:2181,10.0.0.93:2181(CONNECTED) 8] create /wzy666/wzy999/1
Created /wzy666/wzy999/1
[zk: 10.0.0.91:2181,10.0.0.92:2181,10.0.0.93:2181(CONNECTED) 9] create /wzy666/wzy999/2
Created /wzy666/wzy999/[zk: 10.0.0.91:2181,10.0.0.92:2181,10.0.0.93:2181(CONNECTED) 10] ls /wzy666/wzy999
[1, 2][zk: 10.0.0.91:2181,10.0.0.92:2181,10.0.0.93:2181(CONNECTED) 11] delete /wzy666/wzy999
Node not empty: /wzy666/wzy999
6.刪除zookeeper node(遞歸刪除,換句話說,有子目錄也可以被刪除)
[zk: 10.0.0.91:2181,10.0.0.92:2181,10.0.0.93:2181(CONNECTED) 15] deleteall /wzy666/wzy999
[zk: 10.0.0.91:2181,10.0.0.92:2181,10.0.0.93:2181(CONNECTED) 16] ls /wzy666/wzy999
Node does not exist: /wzy666/wzy999
4 zookerper的節點類型
- 臨時zookeeper node:當與客戶端鏈接斷開時,超出了一定的時間范圍(默認30s),則自動刪除該zookeeper node
- 永久zookeeper node:當與客戶端斷開鏈接時,zookeeper node并不會被刪除,除非手動刪除
1.create + -e
可以創建臨時node
[zk: 10.0.0.91:2181,10.0.0.92:2181,10.0.0.93:2181(CONNECTED) 12] create /wzy666/dev
Node does not exist: /zhiyong18/dev
[zk: 10.0.0.91:2181,10.0.0.92:2181,10.0.0.93:2181(CONNECTED) 13] create -e /wzy666/test
Node does not exist: /zhiyong18/test
2.對比2個node的狀態;ephemeralOwner = 0x0 表示永久node,不是則表示臨時node
[zk: 10.0.0.91:2181,10.0.0.92:2181,10.0.0.93:2181(CONNECTED) 22] stat /wzy666/dev
cZxid = 0x20000000d
ctime = Fri Nov 22 10:29:02 UTC 2024
mZxid = 0x20000000d
mtime = Fri Nov 22 10:29:02 UTC 2024
pZxid = 0x20000000d
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 0
numChildren = 0
[zk: 10.0.0.91:2181,10.0.0.92:2181,10.0.0.93:2181(CONNECTED) 23] stat /wzy666/tst
Node does not exist: /wzy666/tst
[zk: 10.0.0.91:2181,10.0.0.92:2181,10.0.0.93:2181(CONNECTED) 24] stat /wzy666/test
cZxid = 0x20000000e
ctime = Fri Nov 22 10:29:09 UTC 2024
mZxid = 0x20000000e
mtime = Fri Nov 22 10:29:09 UTC 2024
pZxid = 0x20000000e
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x5c000066919c0000
dataLength = 0
numChildren = 0
[zk: 10.0.0.91:2181,10.0.0.92:2181,10.0.0.93:2181(CONNECTED) 25]
3.退出30秒,node會被刪除
[zk: 10.0.0.91:2181,10.0.0.92:2181,10.0.0.93:2181(CONNECTED) 0] ls /wzy666/test
Node does not exist: /wzy666/test
4.ephemeralOwner ID和 當前連接終端ID相同,當然也可以用隨機的:create -s
5 watch機制
客戶端可以監控znode狀態,一旦發生變化,就立刻通知客戶端。watch事件是一次性的
1.在第一個會話監視/wzy666的數據
[zk: 10.0.0.91:2181,10.0.0.92:2181,10.0.0.93:2181(CONNECTED) 1] get -w /wzy666
6x6
2.在第二個會話修改數據
[zk: 10.0.0.91:2181,10.0.0.92:2181,10.0.0.93:2181(CONNECTED) 2] set /wzy666 6x9
這時在第一個就能看能通知了
[zk: 10.0.0.91:2181,10.0.0.92:2181,10.0.0.93:2181(CONNECTED) 2]
WATCHER::WatchedEvent state:SyncConnected type:NodeDataChanged path:/wzy666
6 zookerper數據寫入機制
1.客戶端發去數據寫入請求如果到了follwer節點,那么 follower 會轉發寫請求到leader節點;
2.eader 節點接收到寫入請求后,會分配一個全局唯一的事務 ID(ZXID),然后發起寫操作的提案;leader 節點將寫操作的提案廣播給所有 follower 節點
3.每個 follower 節點收到提案后,會嘗試在本地日志中記錄(寫入磁盤),然后向 leader 節點發送一個 ACK(確認消息),表明提案已被記錄
4.當 leader 節點收到超過半數(包括自身)節點的 ACK 后,認為該寫操作被集群大多數接受(滿足 ZooKeeper 的強一致性需求),于是將該事務標記為已提交(commit)。隨后,leader 節點通知所有 follower 節點提交該事務
wzy666
# 6 zookerper數據寫入機制1.客戶端發去數據寫入請求如果到了follwer節點,那么 follower 會轉發寫請求到leader節點;2.eader 節點接收到寫入請求后,會分配一個全局唯一的事務 ID(ZXID),然后發起寫操作的提案;leader 節點將寫操作的提案廣播給所有 follower 節點3.每個 follower 節點收到提案后,會嘗試在本地日志中記錄(寫入磁盤),然后向 leader 節點發送一個 ACK(確認消息),表明提案已被記錄4.當 leader 節點收到超過半數(包括自身)節點的 ACK 后,認為該寫操作被集群大多數接受(滿足 ZooKeeper 的強一致性需求),于是將該事務標記為已提交(commit)。隨后,leader 節點通知所有 follower 節點提交該事務5.最后,leader 節點向客戶端返回寫入成功的響應