【實戰】ZooKeeper 實戰


1. 前言

這篇文章簡單給演示一下 ZooKeeper 常見命令的使用以及 ZooKeeper Java客戶端 Curator 的基本使用。介紹到的內容都是最基本的操作,能滿足日常工作的基本需要。

如果文章有任何需要改善和完善的地方,歡迎在評論區指出,共同進步!

2. ZooKeeper 安裝和使用

2.1. 使用Docker 安裝 zookeeper

a.使用 Docker 下載 ZooKeeper

docker pull zookeeper:3.5.8

b.運行 ZooKeeper

docker run -d --name zookeeper -p 2181:2181 zookeeper:3.5.8

2.2. 連接 ZooKeeper 服務

a.進入ZooKeeper容器中

先使用 docker ps 查看 ZooKeeper 的 ContainerID,然后使用 docker exec -it ContainerID /bin/bash 命令進入容器中。

b.先進入 bin 目錄,然后通過 ./zkCli.sh -server 127.0.0.1:2181命令連接ZooKeeper 服務

root@eaf70fc620cb:/apache-zookeeper-3.5.8-bin# cd bin

如果你看到控制台成功打印出如下信息的話,說明你已經成功連接 ZooKeeper 服務。

2.3. 常用命令演示

2.3.1. 查看常用命令(help 命令)

通過 help 命令查看 ZooKeeper 常用命令

2.3.2. 創建節點(create 命令)

通過 create 命令在根目錄創建了 node1 節點,與它關聯的字符串是"node1"

[zk: 127.0.0.1:2181(CONNECTED) 34] create /node1 “node1”

通過 create 命令在根目錄創建了 node1 節點,與它關聯的內容是數字 123

[zk: 127.0.0.1:2181(CONNECTED) 1] create /node1/node1.1 123
Created /node1/node1.1

2.3.3. 更新節點數據內容(set 命令)

[zk: 127.0.0.1:2181(CONNECTED) 11] set /node1 "set node1"

2.3.4. 獲取節點的數據(get 命令)

get 命令可以獲取指定節點的數據內容和節點的狀態,可以看出我們通過 set 命令已經將節點數據內容改為 "set node1"。

set node1
cZxid = 0x47
ctime = Sun Jan 20 10:22:59 CST 2019
mZxid = 0x4b
mtime = Sun Jan 20 10:41:10 CST 2019
pZxid = 0x4a
cversion = 1
dataVersion = 1
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 9
numChildren = 1

2.3.5. 查看某個目錄下的子節點(ls 命令)

通過 ls 命令查看根目錄下的節點

[zk: 127.0.0.1:2181(CONNECTED) 37] ls /
[dubbo, ZooKeeper, node1]

通過 ls 命令查看 node1 目錄下的節點

[zk: 127.0.0.1:2181(CONNECTED) 5] ls /node1
[node1.1]

ZooKeeper 中的 ls 命令和 linux 命令中的 ls 類似, 這個命令將列出絕對路徑 path 下的所有子節點信息(列出 1 級,並不遞歸)

2.3.6. 查看節點狀態(stat 命令)

通過 stat 命令查看節點狀態

[zk: 127.0.0.1:2181(CONNECTED) 10] stat /node1
cZxid = 0x47
ctime = Sun Jan 20 10:22:59 CST 2019
mZxid = 0x47
mtime = Sun Jan 20 10:22:59 CST 2019
pZxid = 0x4a
cversion = 1
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 11
numChildren = 1

上面顯示的一些信息比如 cversion、aclVersion、numChildren 等等,我在上面 “znode(數據節點)的結構” 這部分已經介紹到。

2.3.7. 查看節點信息和狀態(ls2 命令)

ls2 命令更像是 ls 命令和 stat 命令的結合。 ls2 命令返回的信息包括 2 部分:

  1. 子節點列表
  2. 當前節點的 stat 信息。
[zk: 127.0.0.1:2181(CONNECTED) 7] ls2 /node1
[node1.1]
cZxid = 0x47
ctime = Sun Jan 20 10:22:59 CST 2019
mZxid = 0x47
mtime = Sun Jan 20 10:22:59 CST 2019
pZxid = 0x4a
cversion = 1
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 11
numChildren = 1

2.3.8. 刪除節點(delete 命令)

這個命令很簡單,但是需要注意的一點是如果你要刪除某一個節點,那么這個節點必須無子節點才行。

[zk: 127.0.0.1:2181(CONNECTED) 3] delete /node1/node1.1

在后面我會介紹到 Java 客戶端 API 的使用以及開源 ZooKeeper 客戶端 ZkClient 和 Curator 的使用。

3. ZooKeeper Java客戶端 Curator簡單使用

Curator 是Netflix公司開源的一套 ZooKeeper Java客戶端框架,相比於 Zookeeper 自帶的客戶端 zookeeper 來說,Curator 的封裝更加完善,各種 API 都可以比較方便地使用。

下面我們就來簡單地演示一下 Curator 的使用吧!

Curator4.0+版本對ZooKeeper 3.5.x支持比較好。開始之前,請先將下面的依賴添加進你的項目。

<dependency>
    <groupId>org.apache.curator</groupId>
    <artifactId>curator-framework</artifactId>
    <version>4.2.0</version>
</dependency>
<dependency>
    <groupId>org.apache.curator</groupId>
    <artifactId>curator-recipes</artifactId>
    <version>4.2.0</version>
</dependency>

3.1. 連接 ZooKeeper 客戶端

通過 CuratorFrameworkFactory 創建 CuratorFramework 對象,然后再調用 CuratorFramework 對象的 start() 方法即可!

private static final int BASE_SLEEP_TIME = 1000;
private static final int MAX_RETRIES = 3;

// Retry strategy. Retry 3 times, and will increase the sleep time between retries.
RetryPolicy retryPolicy = new ExponentialBackoffRetry(BASE_SLEEP_TIME, MAX_RETRIES);
CuratorFramework zkClient = CuratorFrameworkFactory.builder()
    // the server to connect to (can be a server list)
    .connectString("127.0.0.1:2181")
    .retryPolicy(retryPolicy)
    .build();
zkClient.start();

對於一些基本參數的說明:

  • baseSleepTimeMs:重試之間等待的初始時間
  • maxRetries :最大重試次數
  • connectString :要連接的服務器列表
  • retryPolicy :重試策略

3.2. 數據節點的增刪改查

3.2.1. 創建節點

我們在 ZooKeeper常見概念解讀 中介紹到,我們通常是將 znode 分為 4 大類:

  • 持久(PERSISTENT)節點 :一旦創建就一直存在即使 ZooKeeper 集群宕機,直到將其刪除。
  • 臨時(EPHEMERAL)節點 :臨時節點的生命周期是與 客戶端會話(session) 綁定的,會話消失則節點消失 。並且,臨時節點 只能做葉子節點 ,不能創建子節點。
  • 持久順序(PERSISTENT_SEQUENTIAL)節點 :除了具有持久(PERSISTENT)節點的特性之外, 子節點的名稱還具有順序性。比如 /node1/app0000000001 、/node1/app0000000002 。
  • 臨時順序(EPHEMERAL_SEQUENTIAL)節點 :除了具備臨時(EPHEMERAL)節點的特性之外,子節點的名稱還具有順序性。

你在使用的ZooKeeper 的時候,會發現 CreateMode 類中實際有 7種 znode 類型 ,但是用的最多的還是上面介紹的 4 種。

a.創建持久化節點

你可以通過下面兩種方式創建持久化的節點。

//注意:下面的代碼會報錯,下文說了具體原因
zkClient.create().forPath("/node1/00001");
zkClient.create().withMode(CreateMode.PERSISTENT).forPath("/node1/00002");

但是,你運行上面的代碼會報錯,這是因為的父節點node1還未創建。

你可以先創建父節點 node1 ,然后再執行上面的代碼就不會報錯了。

zkClient.create().forPath("/node1");

更推薦的方式是通過下面這行代碼, creatingParentsIfNeeded() 可以保證父節點不存在的時候自動創建父節點,這是非常有用的。

zkClient.create().creatingParentsIfNeeded().withMode(CreateMode.PERSISTENT).forPath("/node1/00001");

b.創建臨時節點

zkClient.create().creatingParentsIfNeeded().withMode(CreateMode.EPHEMERAL).forPath("/node1/00001");

c.創建節點並指定數據內容

zkClient.create().creatingParentsIfNeeded().withMode(CreateMode.EPHEMERAL).forPath("/node1/00001","java".getBytes());
zkClient.getData().forPath("/node1/00001");//獲取節點的數據內容,獲取到的是 byte數組

d.檢測節點是否創建成功

zkClient.checkExists().forPath("/node1/00001");//不為null的話,說明節點創建成功

3.2.2. 刪除節點

a.刪除一個子節點

zkClient.delete().forPath("/node1/00001");

b.刪除一個節點以及其下的所有子節點

zkClient.delete().deletingChildrenIfNeeded().forPath("/node1");

3.2.3. 獲取/更新節點數據內容

zkClient.create().creatingParentsIfNeeded().withMode(CreateMode.EPHEMERAL).forPath("/node1/00001","java".getBytes());
zkClient.getData().forPath("/node1/00001");//獲取節點的數據內容
zkClient.setData().forPath("/node1/00001","c++".getBytes());//更新節點數據內容

3.2.4. 獲取某個節點的所有子節點路徑

List<String> childrenPaths = zkClient.getChildren().forPath("/node1");

作者:Snailclimb
鏈接:【實戰】ZooKeeper 實戰
來源:github


免責聲明!

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



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