ZooKeeper入門。
一、ZooKeeper簡介
ZooKeeper 致力於提供一個高效能、高可用,且具備嚴格的順序訪問控制能力的分散式協調服務,是雅虎公司建立,是 Google 的 Chubby 一個開源的實現,也是 Hadoop 和 Hbase 的重要元件。
1. ZooKeeper優點
- 簡單的資料結構:共享的樹形結構,類似檔案系統,儲存於記憶體。
- 可以構建叢集:避免單點故障,3-5 臺機器就可以組成叢集,超過半數正常工作就能對外提供服務。
- 順序訪問:對於每個讀請求,ZooKeeper 會分配一個全域性唯一的遞增編號,利用這個特性可以實現高階協調服務。
- 高效能:基於記憶體操作,服務於非事務請求,適用於讀操作為主的業務場景,3 臺 ZooKeeper 叢集能達到 13w QPS。
2. 那些場景可以使用
- 資料釋出訂閱
- 負載均衡
- 命名服務
- Master 選舉
- 叢集管理
- 配置管理
- 分散式佇列
- 分散式鎖
二、ZooKeeper安裝
ZooKeeper的安裝配置不論是單機安裝還是叢集(或者叢集偽分佈)都是非常的簡單。
首先準備工作
- Linux 需要安裝配置jdk環境。
- 從 ZooKeeper官網 下載 ZooKeeper 安裝包,然後上傳至Linux,我上傳在
/usr/local
目錄下。
下面的內容都是基於 CentOS7 安裝ZooKeeper(3.4.12)。
1. 單機安裝
1、解壓壓縮包。
tar -zxvf zookeeper-3.4.12.tar.gz
2、進入解壓的目錄,將配置檔案zoo_sample.cfg
複製一份為zoo.cfg
,因為 ZooKeeper 啟動時預設配置檔案為zoo.cfg
,當然你也可以指定配置檔案 zoo_sample.cfg
啟動(命令:./zkServer.sh start ../conf/zoo_sample.cfg
)。
cd zookeeper-3.4.12/conf
cp zoo_sample.cfg zoo.cfg
3、修改 zoo_sample.cfg 配置檔案的 dataDir 屬性,這裡存放了 ZooKeeper 的快照檔案,根據自己的需求修改,如果定義的目錄不存在需要先建立出來。
vim zoo.cfg
dataDir=/usr/local/zookeeper-3.4.12/data
4、進入解壓目錄 zookeeper-3.4.12 下的 bin 目錄,啟動 ZooKeeper,相關命令如下:
啟動命令:./zkServer.sh start
停止命令:./zkServer.sh stop
重啟命令:./zkServer.sh restart
狀態檢視命令:./zkServer.sh status
5、啟動後,可以檢視一下狀態是否啟動成功,然後使用命令列進行登入操作,之後就可以嘗試使用 ZooKeeper 的命令列了,命令操作再後面介紹。
./zkCli.sh -server 192.168.182.130:2181
2. 叢集安裝
叢集偽分佈就是在一臺伺服器上面部署多個ZooKeeper,這裡就不使用 叢集偽分佈 來示例了,之前 Redis 有使用過叢集偽分佈,叢集偽分佈就是通過配置檔案埠號區別多個ZooKeeper,叢集最好以奇數個為佳。
過程如下
1、不使用叢集偽分佈,那麼首先準備好三臺Linux伺服器,我這裡使用了三個虛擬機器CentOS7,ip分別為:192.168.182.130、192.168.182.131、192.168.182.132,同時開放 2888 和 3888 這兩個埠訪問,不然叢集無法相互通訊,檢視狀態一直為 ERROR。
2、然後還是和單機安裝一樣,解壓安裝檔案,複製配置檔案,修改配置檔案,不過配置檔案還需要增加一個叢集配置,貼出我的配置,其中:2888:叢集內機器通訊使用(Leader監聽此埠);3888:選舉leader使用。
# The number of milliseconds of each tick
tickTime=2000
# The number of ticks that the initial
# synchronization phase can take
initLimit=10
# The number of ticks that can pass between
# sending a request and getting an acknowledgement
syncLimit=5
# the directory where the snapshot is stored.
# do not use /tmp for storage, /tmp here is just
# example sakes.
dataDir=/usr/local/zookeeper-3.4.12/data
# 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
#
# Be sure to read the maintenance section of the
# administrator guide before turning on autopurge.
#
# http://zookeeper.apache.org/doc/current/zookeeperAdmin.html#sc_maintenance
#
# 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
# 增加的叢集配置
server.0=192.168.182.130:2888:3888
server.1=192.168.182.131:2888:3888
server.2=192.168.182.132:2888:3888
3、配置好 192.168.182.130 這臺伺服器的配置檔案之後,還需要做一件事情,在配置的 dataDir=/usr/local/zookeeper-3.4.12/data
目錄下生成一個myid檔案,分別對應上面配置中的server.0、server.1、server.2,例如 192.168.182.130 對應的就是 0 。
echo 0 > myid
4、將 zookeeper-3.4.12
這個目錄使用 scp
命令遠端複製到 192.168.182.131 和 192.168.182.132這兩個伺服器的 /usr/local
目錄下,遠端複製碰到登入密碼輸入即可,當然,你也可以使用其他工具複製。
scp -r /usr/local/zookeeper-3.4.12 root@192.168.182.131:/usr/local
scp -r /usr/local/zookeeper-3.4.12 root@192.168.182.132:/usr/local
5、前面提到 192.168.182.130 對應配置檔案中的 0,那麼 192.168.182.131 對應的就是 1,192.168.182.132 對應的就是2,所以還需要在這兩臺伺服器上 分別更改 myid 檔案內容。
echo 1 > myid
echo 2 > myid
6、最後分別啟動每個伺服器上的 ZooKeeper 就可以了,分別啟動後可以檢視一下三臺伺服器節點的狀態,如果顯示 Mode: follower
或者 Mode: leader
則代表叢集成功,可以使用以下命令列工具檢視效果。
3. ZooKeeper安裝目錄結構
- bin:存放系統指令碼
- conf:存放配置檔案
- contrib:附加功能支援
- dist-maven:maven 倉庫檔案
- docs:文件
- lib:依賴的第三方庫
- recipes:經典場景樣例程式碼
- src:原始碼
其中 bin 和 conf 是非常重要的兩個目錄,平時也是經常使用的。
bin目錄
常用的兩個:zkServer.sh 為服務端,zkCli 為命令列客戶端。
conf目錄
主要是配置檔案的引數,其中幾個比較重要的如下:
- clientPort:訪問埠,即應用對外服務的埠。
- dataDir:用於存放記憶體資料庫快照的資料夾,同時用於叢集的 myid 檔案也存在這個資料夾裡(注意:一個配置檔案只能包含一個 dataDir 字樣,即使它被註釋掉了),新安裝這資料夾裡面是沒有檔案的,可以通過 snapCount 引數配置產生快照的時機。
- snapCount:每進行 snapCount 次事務日誌輸出後,觸發一次快照(snapshot), 此時,ZooKeeper 會生成一個
snapshot.*
檔案,同時建立一個新的事務日誌檔案log.*
,預設是100000(真正的程式碼實現中,會進行一定的隨機數處理,以避免所有伺服器在同一時間進行快照而影響效能)(Java system property:zookeeper.snapCount )。 - dataLogDir:用於單獨設定 transaction log 的目錄,transaction log 分離可以避免和普通 log 還有快照的競爭。
- tickTime:心跳時間,為了確保連線存在的,以毫秒為單位,最小超時時間為兩個心跳時間。
- initLimit:多少個心跳時間內,允許其他 server 連線並初始化資料,如果 ZooKeeper 管理的資料較大,則應相應增大這個值。
- syncLimit:多少個 tickTime 內,允許 follower 同步,如果 follower 落後太多,則會被丟棄。
三、ZooKeeper特性
1. 會話
客戶端與服務端的一次會話連線,本質是 TCP 長連線,通過會話可以進行心跳檢測和資料傳輸。
會話狀態
ZooKeeper 客戶端和服務端成功連線後,就建立了一次會話,ZooKeeper 會話在整個執行期間的生命週期中,會在不同的會話狀態之間切換,這些狀態包括:CONNECTING、CONNECTED、RECONNECTING、RECONNECTED、CLOSE。
一旦客戶端開始建立 Zookeeper 物件,那麼客戶端狀態就會變成 CONNECTING 狀態,同時客戶端開始嘗試連線服務端,連線成功後,客戶端狀態變為 CONNECTED,通常情況下,由於斷網或其他原因,客戶端與服務端之間會出現斷開情況,一旦碰到這種情況,Zookeeper 客戶端會自動進行重連服務,同時客戶端狀態再次變成 CONNCTING,直到重新連上服務端後,狀態又變為 CONNECTED,在通常情況下,客戶端的狀態總是介於 CONNECTING 和 CONNECTED 之間。但是,如果出現諸如會話超時、許可權檢查或是客戶端主動退出程式等情況,客戶端的狀態就會直接變更為 CLOSE 狀態。
2. 資料模型
ZooKeeper 的檢視結構和 Unix 檔案系統類似,其中每個節點稱為“資料節點”或 ZNode, 每個 znode 可以儲存資料,還可以掛載子節點,因此可以稱之為“樹”,需要注意的是,每一個 znode 都必須有值,如果沒有值,節點是不能建立成功的。
- 在 Zookeeper 中,znode 是一個跟 Unix 檔案系統路徑相似的節點,可以往這個節點儲存或獲取資料。
- 通過客戶端可對 znode 進行增刪改查的操作,還可以註冊 watcher 監控 znode 的變化。
3. 節點型別
zNode有兩種節點型別:持久節點(persistent)、臨時節點(ephemeral)
第一種:持久節點建立:不須其他引數,value可以為任意值,持久節點客戶端斷開連線後不會刪除。
create /SunnyBear value
第二種:臨時節點建立:加上 -e 引數即代表建立臨時節點,客戶端斷開連線後會刪除。
create -e /testSunnyBear ephemeralNodeTest
zNode節點有四種形式的目錄節點:持節節點、持久順序節點、臨時節點、臨時順序節點
持久節點 和 臨時節點 前面已經說了,那麼來看下 持久順序節點 和 臨時順序節點,建立時加上引數 -s 則代表加上了順序,例如分別建立 持久順序節點 和 臨時順序節點。
create -s /SunnyBear2 tests
# 返回了Created /SunnyBear20000000008
create -e -s /testSunnyBear ephemeralNodeTest
# 返回了Created /testSunnyBear0000000009
從上面的結果可以看到,順就節點即在建立的節點名稱後面加上了序號,並且同時需要注意的是,create 命令如果不是建立順序節點,如果節點名稱已經存在是無法建立的,會報錯Node already exists: /SunnyBear
,還有臨時節點不允許有子節點。
4. ZooKeeper節點狀態屬性
屬性 | 資料結構 | 描述 |
---|---|---|
cZxid | long | 節點被建立的Zxid值 |
ctime | long | 節點被建立的時間 |
mZxid | long | 節點被修改的Zxid值 |
mtime | long | 節點被修改的時間 |
pZxid | long | 子節點最後一次被修改時的Zxid值 |
cversion | long | 子節點的版本號 |
dataVersion | long | 節點修改的版本號 |
aclVersion | long | 節點的ACL被修改的版本號 |
ephemeralOwner | long | 如果此節點為臨時節點,那麼它的值為這個節點持有者的會話ID,否則,它的值為0 |
dataLength | int | 節點資料域的長度 |
numChildren | int | 節點擁有的子節點的長度 |
- 其中 Zxid 為 事務id,可以識別出請求的全域性順序。
- 基於 CAS 理論保證分散式資料原子性操作。
5. ACL保障資料的安全
ACL 機制,表示為 scheme?permissions 格式,第一個欄位表示採用哪一種機制,第二個 id 表示使用者,permissions 表示相關許可權(如只讀,讀寫,管理等),詳細的命令使用在後面介紹。
四、命令列
1. 服務端常用命令
啟動命令:./zkServer.sh start
停止命令:./zkServer.sh stop
重啟命令:./zkServer.sh restart
狀態檢視命令:./zkServer.sh status
2. 客戶端常用命令
使用 ./zkCli.sh ip:埠
命令連線到 ZooKeeper,連線成功之後就可以使用下面的命令了,前面也提到了一些命令。
# 檢視當前 ZooKeeper 中根目錄下的子節點資訊
ls /
# 檢視當前 ZooKeeper 中根目錄下子節點資訊,並能看到更新次數等資料
ls2 /
# 建立節點,這個之前已經提到過了,其中-e代表臨時節點,-s代表為順序節點
create [-e] [-s] zNodeName zNodeValue
# 獲取建立節點的資訊
get /zNodeName
# 修改節點內容,這個和redis不同,如果key不存在,那麼會報錯
set /zNodeName zNodeValue
# 刪除節點,如果存在子節點刪除失敗
delte /zNodeName
# 遞迴刪除,子節點同時刪除
rmr /zNodeName
# 退出客戶端
quit
# 幫助命令
help
3. ACL命令常用命令
之前提到了ACL命令為 scheme?permissions 格式,那麼分別看下這三段代表什麼。
- schema:代表授權策略
- id:代表使用者
- permission:代表許可權
scheme
scheme有四種方式:
- world:預設方式,所有人都可以訪問
- auth:代表已經認證通過的使用者
- digest:即使用者名稱:密碼這種方式認證,這也是業務系統中最常用的
- ip:使用ip地址認證
id
和 scheme 一一對應,他也有四種:其中 auth 為明文,digest 為密文
- world -> anyone
- auth -> username:password
- digest -> username:BASE64(SHA1(password))
- ip -> 客戶端ip地址
permission
c(CREATE)、d(DELETE)、r(READ)、w(WRITE)、a(ADMIN)這幾個許可權,對應增,刪,查,改,管理許可權,簡稱cdrwa
- c:建立子節點的許可權
- d:刪除子節點的許可權
- r:讀取節點資料的許可權
- w:修改節點資料的許可權
- a: 給子節點授權的管理許可權
具體命令
# 獲取子節點的ACL資訊
getAcl /zNodeName
# 設定子介面ACL資訊,例如:
# 設定所有人都可以訪問testDir節點,但是卻沒有刪除許可權
setAcl /testDir world:anyone:crwa
# 設定auth方式,先增加使用者再賦予許可權,例如對/testDir目錄下的/testAcl1進行操作
create /testDir/testAcl1 testAcl1
addauth digest user1:123456
setAcl /testDir/testAcl1 auth:user1:123456:crwa
# 設定digest方式,這個和auth的區別就是明文密碼和密文密碼的區別,不適用密文密碼會設定失敗,所以需要獲取密文密碼
# 通過shell命令獲取密文密碼
java -Djava.ext.dirs=/usr/local/zookeeper-3.4.12/lib -cp /usr/local/zookeeper-3.4.12/zookeeper-3.4.12.jar org.apache.zookeeper.server.auth.DigestAuthenticationProvider user2:123456
# 得到結果
user2:123456->user2:hZG2W+NR7DCvADzOkGR6JGLqoTY=
# 接下來就是基本操作了,使用zkCli客戶端登入
create /testDir/testAcl2 testAcl2
addauth digest user2:123456
setAcl /testDir/testAcl2 digest:user2:hZG2W+NR7DCvADzOkGR6JGLqoTY=:crw
# 設定ip方式
create /testDir/testAcl3 testAcl3
set /testDir/testAcl3 ip:192.168.31.6:cdrwa
設定之後就可以使用命令來測試以下許可權是否設定成功了,如果是 auth 和 digest的那麼需要登入來獲取許可權,quit退出連線重新連線ZooKeeper,然後執行下面命令就可測試了。
addauth digest user1:123456
五、ZooKeeper日誌
前面 conf 配置中提交到 dataDir 和 dataLogDir
- dataDir:ZooKeeper 的資料目錄,主要目的是儲存記憶體資料庫序列化後的快照路徑,可以通過 snapCount 引數配置產生快照的時機,預設是100000,但是實際原始碼中會使用 50000 + random(50000) 作為實際產生快照的操作次數,避免多個節點同時產生快照,影響效能。如果沒有配置事務日誌(即dataLogDir配置項)的路徑,那麼 ZooKeeper 的事務日誌也存放在資料目錄中。
- dataLogDir:指定事務日誌的存放目錄。事務日誌對ZooKeeper的影響非常大,強烈建議事務日誌目錄和資料目錄分開,不要將事務日誌記錄在資料目錄(主要用來存放記憶體資料庫快照)下。
快照即類似於 Redis 中的RDB,每 50000 + random(50000) 次記錄操作就生成快照;
事務日誌則類似於 Redis 中的AOF,記錄著每一條操作命令。
檢視快照和事務日誌檔案內容命令
需要注意的是,下面命令的分隔符在window上是;
,在Linux上面是:
,同時還需要注意 jar版本號 和 檔案目錄位置,修改為自己的。
檢視快照:
java -cp ../../zookeeper-3.4.12.jar:../../lib/slf4j-api-1.7.25.jar org.apache.zookeeper.server.SnapshotFormatter snapshot.xxx
檢視事務日誌:
java -cp ../../zookeeper-3.4.12.jar:../../lib/slf4j-api-1.7.25.jar org.apache.zookeeper.server.LogFormatter log.xxx
都讀到這裡了,來個 點贊、評論、關注、收藏 吧!
文章作者:IT王小二
首發地址:https://www.itwxe.com/posts/8c686403/
版權宣告:文章內容遵循 署名-非商業性使用-禁止演繹 4.0 國際 進行許可,轉載請在文章頁面明顯位置給出作者與原文連結。