網(wǎng)站首頁 編程語言 正文
一、ZooKeeper 簡介
ZooKeeper 是一個開源的分布式協(xié)調(diào)服務,目前由 Apache 進行維護。ZooKeeper 可以用于實現(xiàn)分布式系統(tǒng)中常見的發(fā)布/訂閱、負載均衡、命令服務、分布式協(xié)調(diào)/通知、集群管理、Master 選舉、分布式鎖和分布式隊列等功能。 它具有以下特性:
順序一致性: 來自客戶端的更新操作將會按照順序被應用;
?
原子性: 即要么全部更新成功,要么要不更新失敗,沒有部分的結(jié)果;
?
統(tǒng)一的系統(tǒng)鏡像: 即不管客戶端連接的是哪臺服務器,都能看到同樣的服務視圖(也就是無狀態(tài)的)
?
可靠性: 一旦寫入操作被執(zhí)行,那么這個狀態(tài)將會被持久化,直到其它客戶端的修改生效。
?
實時性: 一旦一個事務被成功應用,ZooKeeper 可以保證客戶端立即讀取到這個事務變更后的最新狀態(tài)的數(shù)據(jù)。
1.ZooKeeper 設計目標
- ZooKeeper 致力于為那些高吞吐的大型分布式系統(tǒng)提供一個高性能、高可用、且具有嚴格順序訪問控制能力的分布式協(xié)調(diào)服務。
1)簡單的數(shù)據(jù)模型:
ZooKeeper 通過樹形結(jié)構(gòu)來存儲數(shù)據(jù),它由一系列被稱為 ZNode 的數(shù)據(jù)節(jié)點組成,類似于常見的文件系統(tǒng);
不過和常見的文件系統(tǒng)不同,ZooKeeper 將數(shù)據(jù)全量存儲在內(nèi)存中,以此來實現(xiàn)高吞吐,減少訪問延遲。
2)可配置 Cluster:
為了保證高可用,最好是以集群形態(tài)部署 ZooKeeper,這樣只要集群中大部分機器是可用的,那么 ZooKeeper 本身仍然可用。
上圖中每一個 Server 代表一個安裝 ZooKeeper 服務的服務器,組成 ZooKeeper 服務的服務器都會在內(nèi)存中維護當前的服務器狀態(tài),并且每臺服務器間都保持著通信。并通過 Zab
協(xié)議來保持數(shù)據(jù)的一致性。
3)順序訪問:
對于來自客戶端的每個更新請求,ZooKeeper 都會分配一個全局唯一的遞增 ID,這個 ID 決定了所有事務操作的先后順序。
4)高性能高可用
ZooKeeper 將數(shù)據(jù)全量存儲在內(nèi)存中以保持高性能,并通過服務集群來實現(xiàn)高可用;由于 ZooKeeper 的所有更新和刪除都是基于事務的,所以其在讀多寫少的應用場景中有著很高的性能表現(xiàn)。
2.核心概念
Cluster 角色:
角色 | 作用 |
---|---|
Leader | 提供讀寫服務,并維護集群狀態(tài)(經(jīng)過選舉產(chǎn)生) |
Follower | 提供讀寫服務,并定期向 Leader 匯報自己的節(jié)點狀態(tài)(同時也參加 過半寫成功 的策略和 Leader 的選舉) |
OBServer | 提供讀寫服務,并定期向 Leader 匯報自己的節(jié)點狀態(tài)(因為不參加策略和選舉,所以可以在不影響寫性能的情況下提升集群的讀性能) |
1)Session 會話
當 Client 通過 TCP 長連接 連接到 ZooKeeper 服務器時,Session 便開始建立連接,并通過 tickTime
(心跳檢測)機制來保持有效的會話狀態(tài)。通過這個連接,Client 可以發(fā)送請求并接收響應,同時也可以接收到 Watch 事件的通知。
另外,當由于網(wǎng)絡故障或者 Client 主動斷開等原因,導致連接斷開,此時只要在會話超時時間之內(nèi)重新建立連接,則之間創(chuàng)建的會話依然有效。(這個取決于 tickTime
配置)
2)數(shù)據(jù)節(jié)點
ZooKeeper 數(shù)據(jù)模型是由一系列基本數(shù)據(jù)單元 ZNode(數(shù)據(jù)節(jié)點)組成的節(jié)點樹,其中根節(jié)點為 /
(每個節(jié)點上都會保存自己的數(shù)據(jù)和節(jié)點信息);ZooKeeper 中的節(jié)點可以分為兩大類:
持久節(jié)點: 節(jié)點一旦創(chuàng)建,除非被主動刪除,否則一直存在。
臨時節(jié)點: 一旦創(chuàng)建該節(jié)點的客戶端會話(Session)失效,則所有該客戶端創(chuàng)建的臨時節(jié)點都會被刪除。
3)Watcher
ZooKeeper 中一個常用的功能是 Watcher(事件監(jiān)聽器),它允許用戶在指定節(jié)點上針對感興趣的事件注冊監(jiān)聽,當事件發(fā)生時,監(jiān)聽器會被觸發(fā),并將事件推送到客戶端。該機制是 ZooKeeper 實現(xiàn)分布式協(xié)調(diào)服務的重要特性。
4)ACL
命令 | 作用 |
---|---|
create |
可以進行創(chuàng)建操作 |
read |
可以進行查看操作 |
write |
可以對創(chuàng)建的內(nèi)容進行寫入操作 |
delete |
可以進行刪除操作 |
admin |
可以進行配置權(quán)限操作 |
命令作用create
可以進行創(chuàng)建操作read
可以進行查看操作write
可以對創(chuàng)建的內(nèi)容進行寫入操作delete
可以進行刪除操作admin
可以進行配置權(quán)限操作
3.Zab 協(xié)議介紹
Zab(ZooKeeper Atomic Broadcast 原子廣播)協(xié)議是為分布式協(xié)調(diào)服務 ZooKeeper 專門設計的一種 支持崩潰恢復的原子廣播協(xié)議;
在 ZooKeeper 中,主要依賴 Zab 協(xié)議來實現(xiàn)分布式數(shù)據(jù)一致性;
基于 Zab 協(xié)議,ZooKeeper 實現(xiàn)了一種主備模式的系統(tǒng)架構(gòu)來保持集群中各個副本間的數(shù)據(jù)一致性。
二、ZooKeeper Cluster 安裝
準備工作:
主機名 | 操作系統(tǒng) | IP 地址 |
---|---|---|
ZooKeeper | CentOS 7.4 | 192.168.1.1 |
安裝 JDK:下載地址(需要創(chuàng)建 Oracle 賬號)
[root@ZooKeeper ~]# ls anaconda-ks.cfg jdk-8u181-linux-x64.tar.gz [root@ZooKeeper ~]# tar zxf jdk-8u181-linux-x64.tar.gz [root@ZooKeeper ~]# ls anaconda-ks.cfg jdk1.8.0_181 jdk-8u181-linux-x64.tar.gz [root@ZooKeeper ~]# mv jdk1.8.0_181 /usr/local/java [root@ZooKeeper ~]# cat <> /etc/profile export JAVA_HOME=/usr/local/java export PATH=$PATH:$JAVA_HOME/bin END [root@ZooKeeper ~]# source /etc/profile [root@ZooKeeper ~]# java -version
1.安裝 ZooKeeper
[root@ZooKeeper ~]# wget http://dlcdn.apache.org/zookeeper/zookeeper-3.6.3/apache-zookeeper-3.6.3-bin.tar.gz [root@ZooKeeper ~]# ls anaconda-ks.cfg apache-zookeeper-3.6.3-bin.tar.gz jdk-8u181-linux-x64.tar.gz [root@ZooKeeper ~]# tar zxf apache-zookeeper-3.6.3-bin.tar.gz [root@ZooKeeper ~]# mv apache-zookeeper-3.6.3-bin /usr/local/zookeeper [root@ZooKeeper ~]# mkdir /usr/local/zookeeper/data [root@ZooKeeper ~]# cat <> /usr/local/zookeeper/conf/zoo.cfg tickTime=2000 initLimit=10 syncLimit=5 dataDir=/usr/local/zookeeper/data clientPort=2181 END
注解:
tickTime
:Client 和服務器間的通信會話限制(相當于健康檢查,tickTime 的時間為 ms (1s = 1000ms))
initLimit
:Leader 和 Follower 間初始通信限制。
syncLimit
:Leader 和 Follower 間同步通信限制(當響應時間超于 syncLimit * tickTime 時,Leader 便會將 Follower 進行移除)
dataDir
:此目錄用于存放保存在內(nèi)存數(shù)據(jù)庫中的快照信息(當未配置 dataLogDir 參數(shù)時,日志信息也會存放到此目錄)
clientPort
:ZooKeeper 監(jiān)聽的端口,用于客戶端連接使用。
啟動 ZooKeeper
[root@ZooKeeper ~]# /usr/local/zookeeper/bin/zkServer.sh start # 啟動 [root@ZooKeeper ~]# /usr/local/zookeeper/bin/zkServer.sh status # 查看狀態(tài)
連接到 ZooKeeper
[root@ZooKeeper ~]# /usr/local/zookeeper/bin/zkCli.sh -server 127.0.0.1:2181 Welcome to ZooKeeper! JLine support is enabled WATCHER:: WatchedEvent state:SyncConnected type:None path:null [zk: 127.0.0.1:2181(CONNECTED) 0]
當連接成功后,系統(tǒng)會輸出 ZooKeeper 的相關(guān)配置信息和相關(guān)環(huán)境,并在屏幕上輸出 Welcome to ZooKeeper!
等信息。
2.使用 Golang 連接 ZooKeeper 的 API 接口
安裝 Golang:
[root@ZooKeeper ~]# git clone https://github.com/samuel/go-zookeeper.git [root@ZooKeeper ~]# mv go-zookeeper /usr/local/go/src/
package main import ( "fmt" "time" "go-zookeeper/zk" ) func main() { Hosts := []string{"192.168.1.1:2181"} conn, _, err := zk.Connect(Hosts,time.Second * 5) defer conn.Close() if err != nil { fmt.Println(err) return } }
通過 Golang 實現(xiàn)對 ZooKeeper 的增刪改查:
package main import ( "fmt" "time" "go-zookeeper/zk" ) var ( path = "/Zzz" ) //增 func add(conn *zk.Conn) { var data = []byte("Hello ZooKeeper") // flags 的四種取值方式: // 0 (永久.除非手動刪除) // zk.FlagEphemeral = 1 (短暫. session 斷開則該節(jié)點也被刪除) // zk.FlagSequence = 2 (會自動在節(jié)點后面添加序號) // 3 (Ephemeral 和 Sequence. 即短暫且自動添加序號) var flags int32 = 0 // 獲取訪問控制權(quán)限 acls := zk.WorldACL(zk.PermAll) create, err := conn.Create(path,data,flags,acls) if err != nil { fmt.Printf("創(chuàng)建失敗: %v\n",err) return } fmt.Printf("創(chuàng)建: %v 成功\n",create) } // 查 func get(conn *zk.Conn) { data, _, err := conn.Get(path) if err != nil { fmt.Printf("查詢 %s 失敗,err: %v\n",path,err) return } fmt.Printf("%s 的值為 %s\n",path,string(data)) } // 刪除與增加不同在于其函數(shù)中的 Version 參數(shù). 其中 Version 使用 CAS 支持 (可以通過此種方式保證原子性) // 改 func modify(conn *zk.Conn) { new_data := []byte("This is ZooKeeper") _, sate, _ := conn.Get(path) _, err := conn.Set(path,new_data,sate.Version) if err != nil { fmt.Printf("數(shù)據(jù)修改失敗: %v\n",err) return } fmt.Println("數(shù)據(jù)修改成功") } // 刪 func del(conn *zk.Conn) { _, sate, _ := conn.Get(path) err := conn.Delete(path,sate.Version) if err != nil { fmt.Printf("數(shù)據(jù)刪除失敗: %v\n",err) return } fmt.Println("數(shù)據(jù)刪除成功") } func main() { hosts := []string{"192.168.1.1:2181"} conn, _, err := zk.Connect(hosts,time.Second * 5) defer conn.Close() if err != nil { fmt.Println(err) return } /* 增刪改查 */ add(conn) get(conn) modify(conn) get(conn) del(conn) }
3.配置 ZooKeeper Cluster
在原來的基礎上,在增加兩臺服務器:
主機名 | 操作系統(tǒng) | IP 地址 |
---|---|---|
ZooKeeper-2 | CentOS 7.4 | 192.168.1.2 |
ZooKeeper-3 | CentOS 7.4 | 192.168.1.3 |
1)將 Java 和 ZooKeeper 傳給新的服務器:
[root@ZooKeeper ~]# scp -r /usr/local/java root@192.168.1.2:/usr/local/ [root@ZooKeeper ~]# scp -r /usr/local/zookeeper root@192.168.1.2:/usr/local/
2)在新的服務器上啟動 ZooKeeper:
[root@ZooKeeper ~]# cat <> /etc/profile export JAVA_HOME=/usr/local/java export PATH=$PATH:$JAVA_HOME/bin END [root@ZooKeeper ~]# source /etc/profile [root@ZooKeeper ~]# /usr/local/zookeeper/bin/zkServer.sh start
3)配置 Cluster 集群(三臺服務器上操作一樣)
[root@ZooKeeper ~]# cat <> /usr/local/zookeeper/conf/zoo.cfg server.1=192.168.1.1:2888:3888 server.2=192.168.1.2:2889:3889 server.3=192.168.1.3:2890:3890 END
4)創(chuàng)建 myid
文件
[root@ZooKeeper ~]# echo "1" > /usr/local/zookeeper/data/myid [root@ZooKeeper-2 ~]# echo "2" > /usr/local/zookeeper/data/myid [root@ZooKeeper-2 ~]# echo "3" > /usr/local/zookeeper/data/myid
需要確保每臺服務器的 myid
文件中數(shù)字不同,并且和自己所在機器的 zoo.cfg
中 server.id=host:port:port
的 id
值一樣。
另外,id
的范圍是 1 ~ 255
。
5)重啟 ZooKeeper 服務
[root@ZooKeeper ~]# /usr/local/zookeeper/bin/zkServer.sh restart # 三臺服務器都要重啟
查看 ZooKeeper 狀態(tài):
驗證:
原文鏈接:https://blog.csdn.net/weixin_46902396/article/details/121216278
相關(guān)推薦
- 2023-07-02 python中編寫config文件并及時更新的方法_python
- 2022-10-30 Django視圖層與模板層實例詳解_python
- 2023-07-04 LinkedBlockingQueue與ArrayBlockingQueue對比
- 2023-03-21 解讀torch.nn.GRU的輸入及輸出示例_python
- 2022-11-17 啟動VMware時遇到“vmx86版本不匹配問題”的完美處理方法_VMware
- 2022-11-21 Kotlin?Fragment的具體使用詳解_Android
- 2022-08-21 HTTP協(xié)議詳細介紹_其它綜合
- 2022-06-12 C語言數(shù)據(jù)結(jié)構(gòu)順序表的進階講解_C 語言
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細win安裝深度學習環(huán)境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動態(tài)字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支