ZooKeeper入門


ZooKeeper入門。

作者:IT王小二
博客:https://itwxe.com

一、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

都讀到這里了,來個 點贊、評論、關注、收藏 吧!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM