1. 程式人生 > >zookeeper基本操作

zookeeper基本操作

main方法 通知 nds 重要 syn creat rup 發現 col

  理解Zookeeper的一種方法是將他視為一個提供高可用性的文件系統。它沒有文件和目錄,但是有一個統一概念的節點,叫做znode,作為數據以及其他znode的容器。znode來自於一個層次級的命名空間。傳統的建立成員列表的方法是以小組的名稱創建一個父znode,同時子znode使用的是組成員的名稱。

  1.創建組

  下面要寫一個為組創建一個znode的程序,來介紹一下Zookeeper 的Java API。如下:

public class ConnectionManager implements Watcher{

    private static final int SESSION_TIMEOUT = 5000
; protected ZooKeeper zk; private CountDownLatch countDownLatch = new CountDownLatch(1); public void connect(String hosts) throws IOException, InterruptedException { zk = new ZooKeeper(hosts,SESSION_TIMEOUT,this); countDownLatch.await(); } public void process(WatchedEvent watchedEvent) {
if(watchedEvent.getState() == Event.KeeperState.SyncConnected) { countDownLatch.countDown(); } } public void close() throws InterruptedException { zk.close(); } }
public class CreateGroup extends ConnectionManager{

    public void createGroup(String groupName) throws KeeperException, InterruptedException {
        String path 
= "/" + groupName; String createPath = zk.create(path,null, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT); System.out.println("Create:"+createPath); } public static void main(String[] args) throws IOException, InterruptedException, KeeperException { CreateGroup group = new CreateGroup(); group.connect("localhost"); group.createGroup("/zoo"); group.close(); } }

  main方法執行的時候,先創建一個CreateGroup對象,並調用它的connect方法,此方法實例化一個新的zookeeper對象,他是客戶端API的主要類並且維護著客戶端和zookeeper服務端的鏈接。這個構造函數有三個參數,第一個是Zookeeper的主機地址,第二個是每個會話的超時時間,第三個是Watcher對象的實例,Watcher接收Zookeeper的響應,並通知它各種事件,這個例子中ConnectionManager是一個Watcher,因此我們將他傳遞給Zookeeper的構造函數。

  當一個zookeeper的實例被創建後,它啟動一個線程鏈接到zookeeper服務。對構造函數的響應返回很快,因此在使用zookeeper對象前等待鏈接建立非常重要。在這裏我們使用Java的CountDownLatch來阻塞,直到zookeeper準備好客戶端鏈接到zookeeper後,Watcher的process方法會被調用,並收到一個事件,表明鏈接已經建立。當收到該事件的時候,我們使用CountDownLatch的countDown操作減掉一個計數。此時計數器歸0,await方法返回。當connect方法完成後,調用createGroup方法。在這個方法裏我們使用zookeeper的create方法創建一個新的zookeeper的node。znode可能是臨時的或則永久性的。一個臨時性的znode,在客戶端與服務端斷開連接後,服務端便把節點刪除。create方法的返回值是ZookEeper的創建路徑。

  2加入組

  下面是一個將成員註入到組裏的程序,每一個程序在程序運行的時候加入到組中,當程序結束的時候,它必須從這個組中移除。我們可以在Zookeeper的命名空間下創建臨時節點來實現。

public class JoinGroup extends ConnectionManager{

    public void joinGroup(String groupName,String memberName) throws KeeperException, InterruptedException {
        String path = "/" + groupName + "/" + memberName;
        String createPath = zk.create(path,null, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
        System.out.println("Create:"+createPath);
    }

    public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
        JoinGroup group = new JoinGroup();
        group.connect("localhost");
        group.joinGroup("/zoo","test");
        group.close();
    }
}

  JoinGroup與CreateGroup十分的相似,在joinGroup中創建一個臨時的節點作為znode的子節點,最後會看到在程序結束的時候,臨時節點也相應的被刪除。

  3.列出組成員

  現在我們實現一個程序,找出組中的成員,實現如下:
  

public class ListGroup extends ConnectionManager{

    public void listGroup(String groupName) throws KeeperException, InterruptedException {
        String path = "/" + groupName;
        List<String> children = zk.getChildren(path,false);
        if(children.isEmpty()){
            System.out.println("no child");
            System.exit(1);
        }else{
            for(String child : children){
                System.out.println(child);
            }
        }
    }

    public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
        ListGroup group = new ListGroup();
        group.connect("localhost");
        group.listGroup("/zoo");
        group.close();
    }
}

  4.刪除一個組

  Zookeeper提供了一個帶有路徑和版本號的delete方法,Zookeeper只在刪除的znode的版本號和已經定義過的版本號一樣的時候才會刪除該znode,樂觀鎖機制能夠使客戶端發現znode修改的沖突,你可以不管版本號而使用版本號-1來刪除該znode。早zookeeper中沒有遞歸刪除操作,因此在刪除父節點前要先刪除子節點信息

  

public class DeleteGroup extends ConnectionManager{

    public void deleteGroup(String groupName) throws KeeperException, InterruptedException {
        String path = "/" + groupName;
        List<String> children = zk.getChildren(path,false);
        for(String child : children){
            String tempPath = path + "/" + child;
            List<String> temp = zk.getChildren(tempPath,false);
            if(temp.isEmpty()) {
                zk.delete(path + "/" + child, -1);
            }else{
                deleteGroup(tempPath);
            }
        }
        zk.delete(path,-1);
    }

    public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
        DeleteGroup group = new DeleteGroup();
        group.connect("localhost");
        group.deleteGroup("/zoo");
        group.close();
    }
}

  

zookeeper基本操作