Zookeeper命令列以及java API簡單使用

來源:互聯網
上載者:User

安裝
關於zookeeper的安裝,請參考這篇文章:ZooKeeper偽分布式叢集安裝及使用

我在這裡使用的是文中提到的zookeeper偽分布模式的安裝和使用。

命令列
下面說明命令列方式下使用zookeeper。
切換到zookeeper安裝目錄的bin目錄下:

命令:zkServer.sh start zoo0.cfg
該命令啟動zkServer伺服器。我這裡使用的是偽分布模式,三個伺服器都是本機,只不過採用不同的連接埠號碼而已,並配置在不同的設定檔中,即zoo0.cfg、zoo1.cfg、zoo2.cfg這三個檔案中配置了相應的參數和連接埠號碼。

啟動了三個伺服器之後,查看三個伺服器的狀態:

命令:zkServer.sh status zoo0.cfg
三個伺服器的狀態有兩種,一種跟隨狀態,一種處於領導狀態。

伺服器啟動之後,可以通過用戶端進行串連,如下:

命令:zkCli.sh -server centos:2181
其中centos是我的主機名稱,2181是設定檔中配置的用戶端串連伺服器的連接埠號碼,可以在zoo0.cfg檔案中查看到這個配置。相應的,按照我的偽分布配置,zkCli.sh -server centos:2182 這個命令可以串連到我的第二個伺服器,該配置可以在zoo1.cfg檔案中。大家在使用該命令時,需要按照自己的配置相應的更改一下即可。
通過上面的日誌,Welcom to ZooKeeper。輸出說明用戶端串連伺服器成功。。

輸入help命令:

通過該命令,我們可以查看到用戶端可以使用的命令列有哪些。。。
其實也不多,就這麼幾個。

命令:
ls /
stat /zookeeper

ls /命令查看根節點下的節點有哪些。可以看到只有zookeeper一個節點。
stat /zookeeper命令查看節點zookeeper節點的狀態資訊。

cZxid表示建立該節點時候的zxid,
mZxid表示當前的,
zxid是用來為選舉leader服務的。

ctime和mtime,前者表示建立的時間,後者表示最近一次更新的時間。
要注意的是ctime就定死了建立的那一刻,而mtime會在你調用更改節點函數的時候重新設定;
但是exists和get是不會引起其更新的。

命令:get /nodename

命令get /nodename擷取節點路徑的資料。注意:path必須是絕對路徑,也就是path必須是/開頭的路徑。
剛開始節點沒有儲存資料,所以,這裡的三個節點下均無資料。

擷取子節點quota資訊:

設定資料命令:
set /nodepath 資料資訊

圖中設定根節點的資料為字串“longyin”,然後命令擷取:get /
可以看到dataLength的數值也跟著變化了。

建立節點:create /path data

建立節點node,然後通過ls輸出根節點下的子節點有兩個。

擷取資料並刪除節點,命令:
get /node
delete /node

退出用戶端,命令:
quit
java API 介面操作

import java.io.IOException;import org.apache.zookeeper.CreateMode;import org.apache.zookeeper.KeeperException;import org.apache.zookeeper.WatchedEvent;import org.apache.zookeeper.Watcher;import org.apache.zookeeper.ZooDefs.Ids;import org.apache.zookeeper.ZooKeeper;public class BasicDemo1 {    public static void main(String[] args)                 throws IOException, KeeperException, InterruptedException {        /**         *  建立一個與伺服器的串連         *  參數一:伺服器位址和連接埠號碼(該連接埠號碼值伺服器允許用戶端串連的連接埠號碼,設定檔的預設連接埠號碼2181)         *  參數二:串連會話逾時時間         *  參數三:觀察者,串連成功會觸發該觀察者。不過只會觸發一次。         *      該Watcher會擷取各種事件的通知         */        ZooKeeper zk = new ZooKeeper("centos:2181", 60000, new Watcher() {            // 監控所有被觸發的事件            public void process(WatchedEvent event) {                System.out.println("監控所有被觸發的事件:EVENT:" + event.getType());            }        });        System.out.println("*******************************************************");        // 查看根節點的子節點        System.out.println("查看根節點的子節點:ls / => " + zk.getChildren("/", true));        System.out.println("*******************************************************");        // 建立一個目錄節點        if (zk.exists("/node", true) == null) {            /**             * 參數一:路徑地址             * 參數二:想要儲存的資料,需要轉換成位元組數組             * 參數三:ACL存取控制清單(Access control list),             *      參數類型為ArrayList<ACL>,Ids介面提供了一些預設的值可以調用。             *      OPEN_ACL_UNSAFE     This is a completely open ACL              *                          這是一個完全開放的ACL,不安全             *      CREATOR_ALL_ACL     This ACL gives the             *                           creators authentication id's all permissions.             *                          這個ACL賦予那些授權了的使用者具備許可權             *      READ_ACL_UNSAFE     This ACL gives the world the ability to read.             *                          這個ACL賦予使用者讀的許可權,也就是擷取資料之類的許可權。             * 參數四:建立的節點類型。枚舉值CreateMode             *      PERSISTENT (0, false, false)             *      PERSISTENT_SEQUENTIAL (2, false, true)             *          這兩個類型建立的都是持久型類型節點,回話結束之後不會自動刪除。             *          區別在於,第二個類型所建立的節點名後會有一個單調遞增的數值             *      EPHEMERAL (1, true, false)             *      EPHEMERAL_SEQUENTIAL (3, true, true)             *          這兩個類型所建立的是臨時型類型節點,在回話結束之後,自動刪除。             *          區別在於,第二個類型所建立的臨時型節點名後面會有一個單調遞增的數值。             * 最後create()方法的傳回值是建立的節點的實際路徑             */            zk.create("/node", "conan".getBytes(),                    Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);            System.out.println("建立一個目錄節點:create /node conan");            /**             *  查看/node節點資料,這裡應該輸出"conan"             *  參數一:擷取節點的路徑             *  參數二:說明是否需要觀察該節點,設定為true,則設定共用預設的觀察器             *  參數三:stat類,儲存節點的資訊。例如資料版本資訊,建立時間,修改時間等資訊             */            System.out.println("查看/node節點資料:get /node => "                    + new String(zk.getData("/node", false, null)));            /**             * 查看根節點             * 在此查看根節點的值,這裡應該輸出上面所建立的/node節點             */            System.out.println("查看根節點:ls / => " + zk.getChildren("/", true));        }        System.out.println("*******************************************************");        // 建立一個子目錄節點        if (zk.exists("/node/sub1", true) == null) {            zk.create("/node/sub1", "sub1".getBytes(),                    Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);            System.out.println("建立一個子目錄節點:create /node/sub1 sub1");            // 查看node節點            System.out.println("查看node節點:ls /node => "                    + zk.getChildren("/node", true));        }        System.out.println("*******************************************************");        /**         *  修改節點資料         *  修改的資料會覆蓋上次所設定的資料         *  setData()方法參數一、參數二不多說,與上面類似。         *  參數三:數值型。需要傳入該介面的數實值型別版本號碼。。。         *      該資訊可以通過Stat類擷取,也可以通過命令列擷取。         *      如果該值設定為-1,就是忽視版本匹配,直接設定節點儲存的值。         */        if (zk.exists("/node", true) != null) {            zk.setData("/node", "changed".getBytes(), -1);            // 查看/node節點資料            System.out.println("修改節點資料:get /node => "                    + new String(zk.getData("/node", false, null)));        }        System.out.println("*******************************************************");        // 刪除節點        if (zk.exists("/node/sub1", true) != null) {            zk.delete("/node/sub1", -1);            zk.delete("/node", -1);            // 查看根節點            System.out.println("刪除節點:ls / => " + zk.getChildren("/", true));        }        // 關閉串連        zk.close();    }}

代碼中大部分關鍵代碼已經給出了詳細的注釋。程式碼完成的功能也和命令列相同。首先啟動zookeeper,然後運行代碼:
結果如下:

可以看到,結果和我們使用命令列的操作一樣的效果。代碼中我們可以使用觀察者,接收各種事件。

最後再給出一個小範例程式碼:

import java.io.IOException;import java.util.ArrayList;import org.apache.zookeeper.CreateMode;import org.apache.zookeeper.KeeperException;import org.apache.zookeeper.WatchedEvent;import org.apache.zookeeper.Watcher;import org.apache.zookeeper.ZooKeeper;import org.apache.zookeeper.ZooDefs.Ids;public class QueueZooKeeper {    public static void main(String[] args) throws Exception {        if (args.length == 0) {            doOne();        } else {            doAction(Integer.parseInt(args[0]));        }    }    public static void doOne() throws Exception {        String host1 = "centos:2181";        ZooKeeper zk = connection(host1);        initQueue(zk);        joinQueue(zk, 1);        joinQueue(zk, 2);        joinQueue(zk, 3);        zk.close();    }    public static void doAction(int client) throws Exception {        String host1 = "centos:2181";        String host2 = "centos:2182";        String host3 = "centos:2183";        ZooKeeper zk = null;        switch (client) {        case 1:            zk = connection(host1);            initQueue(zk);            joinQueue(zk, 1);            break;        case 2:            zk = connection(host2);            initQueue(zk);            joinQueue(zk, 2);            break;        case 3:            zk = connection(host3);            initQueue(zk);            joinQueue(zk, 3);            break;        }    }    // 建立一個與伺服器的串連    public static ZooKeeper connection(String host) throws IOException {        ZooKeeper zk = new ZooKeeper(host, 60000, new Watcher() {            // 監控所有被觸發的事件            public void process(WatchedEvent event) {                if (event.getType() == Event.EventType.NodeCreated                            && event.getPath().equals("/queue/start")) {                    System.out.println("Queue has Completed.Finish testing!!!");                }            }        });        return zk;    }    public static void initQueue(ZooKeeper zk)            throws KeeperException, InterruptedException {        System.out.println("WATCH => /queue/start");//        zk.exists("/queue/start", true);        /**         * 建立節點/queue.永久節點         * 存在則不建立,如果不存在,則建立         */        if (zk.exists("/queue", false) == null) {            System.out.println("create=> /queue task-queue");            zk.create("/queue", "task-queue".getBytes(),                    Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);        } else {            System.out.println("/queue is exist!");        }    }    /**     * 建立節點/queue的子節點,(臨時節點),在會話退出之後,臨時節點刪除。並且臨時     * 節點有順序號。     * @param zk     * @param x     * @throws KeeperException     * @throws InterruptedException     */    public static void joinQueue(ZooKeeper zk, int x)            throws KeeperException, InterruptedException {        System.out.println("create=> /queue/x" + x + " x" + x);        zk.create("/queue/x" + x, ("x" + x).getBytes(),                Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);        isCompleted(zk);    }    public static void isCompleted(ZooKeeper zk)            throws KeeperException, InterruptedException {        int size = 3;        ArrayList<String> list = (ArrayList<String>)                 zk.getChildren("/queue", true);        for (String str:list) {            System.out.println("擷取節點queue的子節點:ls /queue:"+str);        }        int length = list.size();        System.out.println("Queue Complete:" + length + "/" + size+"(子節點個數/總長度)");        if (length >= size) {            System.out.println("建立臨時型節點:create /queue/start start");            zk.create("/queue/start", "start".getBytes(),                    Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);        }     }}

運行結果如下:

從上面的結果可以看出,我們建立臨時型節點的時候,會話結束,臨時節點自動刪除。我們使用命令列查看一下根節點的資訊:

代碼中建立的節點都沒有了。

另一個要注意的是,我們使用的節點類型是臨時型的有順序號的節點類型,我們發現,會話期間,我們列印的節點名後面有000000014,000000015,000000016,由於我運行了幾次代碼,所以這個值在單條遞增,增加到了16,從這裡我們應該知道了順序號類型的節點的意思了。

OK,結束。

本項目的代碼地址:請猛戳這裡(歡迎關注我的GITHUB)
項目使用eclipse構建。方便易用,代碼注釋詳細。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.