zookeeper入門

IT王小二發表於2021-06-24

ZooKeeper入門。

一、ZooKeeper簡介

ZooKeeper 致力於提供一個高效能、高可用,且具備嚴格的順序訪問控制能力的分散式協調服務,是雅虎公司建立,是 Google 的 Chubby 一個開源的實現,也是 Hadoop 和 Hbase 的重要元件。

1. ZooKeeper優點

  1. 簡單的資料結構:共享的樹形結構,類似檔案系統,儲存於記憶體。
  2. 可以構建叢集:避免單點故障,3-5 臺機器就可以組成叢集,超過半數正常工作就能對外提供服務。
  3. 順序訪問:對於每個讀請求,ZooKeeper 會分配一個全域性唯一的遞增編號,利用這個特性可以實現高階協調服務。
  4. 高效能:基於記憶體操作,服務於非事務請求,適用於讀操作為主的業務場景,3 臺 ZooKeeper 叢集能達到 13w QPS。

2. 那些場景可以使用

  • 資料釋出訂閱
  • 負載均衡
  • 命名服務
  • Master 選舉
  • 叢集管理
  • 配置管理
  • 分散式佇列
  • 分散式鎖

二、ZooKeeper安裝

ZooKeeper的安裝配置不論是單機安裝還是叢集(或者叢集偽分佈)都是非常的簡單。

首先準備工作

  1. Linux 需要安裝配置jdk環境。
  2. 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節點狀態屬性

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 配置中提交到 dataDirdataLogDir

  • 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 國際 進行許可,轉載請在文章頁面明顯位置給出作者與原文連結。

相關文章