zookeeper客戶端(一)原生Zookeeper API的使用

目錄

1、zookeeper自帶的zkCli客戶端命令行

2、使用zookeeper原生API


1、zookeeper自帶的zkCli客戶端命令行

當進入zkCli的命令行,可以輸入help顯示出所有操作的命令,如下表:

命令基本語法

功能描述

help

顯示所有操作命令

ls path [watch]

使用 ls 命令來查看當前znode中所包含的內容

ls2 path [watch]

查看當前節點數據並能看到更新次數等數據

create

普通創建

-s  含有序列

-e  臨時(重啓或者超時消失)

get path [watch]

獲得節點的值

set

設置節點的具體值

stat

查看節點狀態

delete

刪除節點

rmr

遞歸刪除節點

示例:

查看所有節點: ls /          ls2  / (顯示的更詳細)

創建普通節點: create path  data
    	      如:create  /xiyou  "sunwukong"

獲取節點值:get  path
		   如:get /xiyou

創建臨時節點:create   -e    /sanguo  "xiaoqiao"
            創建的這個臨時節點,在客戶端退出時就會被刪除

創建帶序號節點:create -s  /xiyou/sunhouzi  "sunwukong"
	
修改節點的值: set  path  data
		      如:set /xiyou   "wujing"

節點的值變化監聽:get  /xiyou   watch(說明:這種監聽只會生效一次)
   驗證:可以在A客戶端中執行監聽,在B客戶端修改/xiyou的值,此時A客戶端會出現如下提示
   WatchedEvent state:SyncConnected type:NodeDataChanged path:/sanguo/simayi
   說明監聽節點的值已被修改。

節點路徑的變化監聽:ls  /sanguo  watch(說明:這種監聽只會生效一次)
	驗證:在A客戶端執行監聽,通過B客戶端在/sanguo目錄下新增一個節點,在hadoop102上觀察效果
	在A客戶端會出現如下提示:
	WatchedEvent state:SyncConnected type:NodeChildrenChanged path:/sanguo


刪除節點(子節點):delete  /xiyou/bajie

遞歸刪除節點: rmr  /xiyou

查看節點狀態: stat  /sanguo

2、使用zookeeper原生API

(1)環境搭建

      使用maven工程,在pom.xml中引入原生的Zookeeper API。

<!--zookeeper原生API -->
<dependency>
     <groupId>org.apache.zookeeper</groupId>
     <artifactId>zookeeper</artifactId>
     <version>3.4.10</version>
</dependency>

<!-- 單元測試-->
<dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      version>4.12</version>
      <scope>compile</scope>
/dependency>

(2)代碼示例

a、創建客戶端

new Zookeeper(zookeeper地址, session超時時間, 監聽事件)

原生的zookeeper存在缺陷:註冊事件只生效一次,因此需要人爲在process回調中再次註冊監聽事件

    @Before
    public void initZk() throws Exception {
          zooKeeper = new ZooKeeper(connectString, sessionTimeout, new Watcher() {
            public void process(WatchedEvent watchedEvent) {
                //監聽發生後觸發的事件
                System.out.println(watchedEvent.getType() + "---" + watchedEvent.getPath());

                //再次註冊事件進行監聽
                try {
                    zooKeeper.exists("/liuzhoujian", true);
                    zooKeeper.getChildren("/", true);
                } catch (KeeperException e) {
                    e.printStackTrace();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
    }

b、創建節點

    @Test
    public void createNode() throws Exception {
        //第一個參數:節點路徑
        //第二個參數:存儲的數據
        //第三個參數:訪問的權限
        //第四個參數:節點的類型
        String node = zooKeeper.create("/liuzhoujian", "movie.txt".getBytes(),
                ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
        System.out.println(node);
    }

c、刪除節點

當不需要某個節點,或者某個節點的信息已經失效時,使用delete方法可以刪除節點,刪除時需要指定節點的版本號,如果設置爲-1,則匹配所有版本,zookeeper會比較刪除的節點版本是否和服務器上的版本一致,如果不一致則拋出異常。

zookeeper.delete("/liuzhoujian", -1);

d、設置和獲取節點內容

setData設置數據,getData獲取數據,其中每個節點最多存入1M數據。

getData() 第一個參數:節點路徑   第二個參數:是否使用監聽,false表示不使用  第三個參數:stat 表示節點的狀態,將會返回該節點當前的狀態信息

//設置版本號爲-1,如果匹配不到相應節點會拋出異常
zooKeeper.setData("/liuzhoujian", "hello".getBytes(), -1);
        
Stat stat = new Stat();
byte[] data = zooKeeper.getData("/liuzhoujian", false, stat);
        

e、添加子節點

 String parent= zooKeeper.create("/liuzhoujian", "parent".getBytes(),
                ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);

 String child = zooKeeper.create("/liuzhoujian/child", "child".getBytes(),
                ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);

f、判斷節點是否存在

    @Test
    public void isExist() throws Exception {
        Stat stat = zooKeeper.exists("/liuzhoujian", true); //watch爲true表示開啓監聽,默認只監聽一次,需在process回調中再次配置
        System.out.println(stat == null ? "nost exist" : "exist");
        Thread.sleep(Long.MAX_VALUE); //爲了阻塞,能觀察到監聽器的處理效果
    };

g、獲取根目錄下所有節點


    @Test
    public void getNode() throws Exception {
        List<String> children = zooKeeper.getChildren("/", true);
        for(String node : children) {
            System.out.println(node);
        }

        Thread.sleep(Long.MAX_VALUE);
    }

g、watcher的實現

當節點狀態發生變化時,通過watcher繪製,可以讓客戶端得到通知,watcher需要實現org.apache.ZooKeeper.Watcher接口。節點的狀態變化主要分爲:

節點狀態變化 解釋
EventType.NodeDeleted 刪除節點
EventType.NodeChildrenChanged 修改節點的子節點
EventType.NodeCreated 創建節點
EventType.NodeDataChanged 修改節點數據
public class ZKWatcher implementes Watcher {
    @Override
    public void process(WatchedEvent event) {    
                //監聽發生後觸發的事件
                if(event.getType() == Event.EventType.NodeDeleted) {
                    System.out.println("node deleted");
                } else if(event.getType() == Event.EventType.NodeChildrenChanged) {
                    System.out.println("nodeChildrenChanged");
                } else if(event.getType() == Event.EventType.NodeCreated) {
                    System.out.println("node created");
                } else if(event.getType() == Event.EventType.NodeDataChanged) {
                    System.out.println("node data changed");
                }
    }
}

需要注意的是:Zookeeper的watcher是一次性的,每次在處理完狀態變化事件後,需要重新註冊watcher。這個特性也使得在處理時間和重新加上watcher這段時間發生的節點狀態變化無法被感知。

文章參考:《大型分佈式網站架構設計與實踐》

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章