ZooKepper API

1.ZooKeeper API的基础知识

与ZooKeeper集合进行交互的应用程序成为ZooKeeper客户端或简称客户端.

Znode是ZooKeeper集合的核心组件,ZooKeeper API提供了一小组方法使用ZooKeeper集合来操纵znode的所有细节.

客户端应该遵循以下步骤,与ZooKeeper集合进行清晰和干净的交互.

  连接到ZooKeeper集合.ZooKeeper集合为客户端分配会话ID.

  定期向服务器发送心跳,否则,ZooKeeper集合将过期会话ID,客户端需要重新连接.

  只要会话ID处于活动状态,就可以获取/设置znode.

  所有任务完成后,断开与ZooKeeper集合的连接,如果客户端长时间不活动,则ZooKeeper集合将自动断开客户端.

Java绑定

让我们了解本章中最重要的一组ZooKeeper API.ZooKeeper API 的核心部分是ZooKeeper类.它提供了在其构造函数中连接ZooKeeper集合的选项,并具有以下方法

  connect - 连接到ZooKeeper集合

  create - 创建znode

  exists - 检查znode是否存在及其信息

  getData - 从特定的znode中获取数据

  setData - 在特定的znode中设置数据

  getChildren - 获取特定znode中的所有子节点

  delete - 删除特定的znode及其所有子项

  close - 关闭连接

连接到ZooKeeper集合

ZooKeeper类通过其构造函数提供connect功能.构造函数的签名如下

ZooKeeper(String connectionString, int sessionTimeout, Watcher watcher)

connectionString - ZooKeeper集合主机.

sessionTimeout - 会话超时(以毫秒为单位).

watcher - 实现"监视器"界面的对象.ZooKeeper集合通过监视器对象返回连接状态.

import java.io.IOException;
import java.util.concurrent.CountDownLatch;

import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.Watcher.Event.KeeperState;
import org.apache.zookeeper.ZooKeeper;

public class ZooKeeperConnector {

    private ZooKeeper zoo;
    final CountDownLatch connectedSignal = new CountDownLatch(1);
    public ZooKeeper connect(String host) throws IOException, InterruptedException {
        zoo = new ZooKeeper(host, 5000,new Watcher() {
            @Override
            public void process(WatchedEvent event) {
                if (event.getState() == KeeperState.SyncConnected) {
                    connectedSignal.countDown();
                }
            }
        });
        connectedSignal.await();
        return zoo;
    }
    public void close() throws InterruptedException {
        zoo.close();
    }
}

创建Znode

ZooKeeper类提供了在ZooKeeper集合中创建一个新的znode的create方法.create方法的签名如下:

create(String path, byte[] data, List<ACL> acl, CreateMode createMode)

path - Znode路径.例如,/myapp1,/myapp2,/myapp1/mydata1,myapp2/mydata1/myannothersubdata

data - 要存储在指定znode路径中的数据

acl - 要创建的节点的访问控制列表.ZooKeeper API提供了一个静态接口ZooDefs.Ids类获取一些基本的acl列表.例如,ZooDefs.Ids.OPEN_ACL_UNSAFE返回打开znode的的acl列表.

createMode - 节点的类型,即临时,顺序或两者.这是一个美剧

让我们创建一个新的Java应用程序来检查ZooKeeper API的create功能.创建文件ZKCreate.java.在main方法中,创建一个类型为ZooKeeperConnection的对象,并调用connect方法连接到ZooKeeper集合.

connect方法将返回ZooKeeper对象zk.现在,请使用自定义path和data调用zk对象的create方法.

创建znode的完整程序代码如下:

Exists - 检查Znode的存在

ZooKeeper类提供了 exists方法来检查znode的存在.如果指定的znode存在,则返回一个znode的元数据.exists方法的签名如下:

exists(String path, boolean watcher)

path - Znode路径

watcher - 布尔值,用于指定是否监视指定的znode

让我们创建一个新的Java应用 程序来检查ZooKeeper API的 "exists"功能.创建文件 "ZKExists.java".在main方法中,使用"ZooKeeperConnection"对象创建ZooKeeper对象"zk".然后,使用自定义"path"调用"zk"对象的"exists"方法.完整的列表如下:

import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.data.Stat;

public class ZKExists {
    private static ZooKeeper zk;
    private static ZooKeeperConnector conn;

    public static Stat znodeExists(String path) throws KeeperException, InterruptedException {
        return zk.exists(path, true);
    }

    public static void main(String[] args) {
        String path = "/MyFirstZnode";// Assign znode to the specified path

        try {
            conn = new ZooKeeperConnector();
            zk = conn.connect("localhost");
            Stat stat = znodeExists(path);// Stat checks the path of the znode
            if (stat != null) {
                System.out.println("Node exists and the node version is " + stat.getVersion());
            } else {
                System.out.println("Node does not exists");
            }
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }

}

 getData方法

ZooKeeper类提供getData方法来获取附加在指定znode中的数据及其状态.getData方法的签名如下

getData(String path, Watcher watcher, Stat stat)

  path - Znode路径

  watcher - 监视器类型的回调函数.当指定的znode的数据改变时,ZooKeeper集合将通过监视器回调进行通知.这是一次性通知.

  stat - 返回znode的元数据

让我们创建一个新的Java应用程序来了解ZooKeeper API的getData功能.创建文件ZKGetData.java.在main方法中.使用ZooKeeperConnector对象创建一个ZooKeeper对象zk.然后,使用自定义路径调用zk对象的getData方法.

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.concurrent.CountDownLatch;

import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.data.Stat;

public class ZkGetData {

    private static ZooKeeper zk;
    private static ZooKeeperConnector conn;

    public static Stat znodeExists(String path) throws KeeperException, InterruptedException {
        return zk.exists(path, true);
    }

    public static void main(String[] args) {
        String path = "/MyFirstZnode";
        final CountDownLatch connectedSignal = new CountDownLatch(1);

        try {
            conn = new ZooKeeperConnector();
            zk = conn.connect("localhost");
            Stat stat = znodeExists(path);

            if (stat != null) {
                byte[] b = zk.getData(path, new Watcher() {
                    @Override
                    public void process(WatchedEvent we) {
                        if (we.getType() == Event.EventType.None) {
                            switch (we.getState()) {
                            case Expired:
                                connectedSignal.countDown();
                                break;
                            }
                        } else {
                            try {
                                byte[] bn = zk.getData(path, false, null);
                                String data = new String(bn, "UTF-8");
                                System.out.println(data);
                                connectedSignal.countDown();
                            } catch (UnsupportedEncodingException | KeeperException | InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }, null);
                String data = new String(b, "UTF-8");
                System.out.println(data);
                connectedSignal.await();
            } else {
                System.out.println("Node does not exists");
            }
        } catch (IOException | InterruptedException | KeeperException e) {
            System.out.println(e.getMessage());
        }
    }
}

一旦编译和执行应用程序,你将获得以下输出

My first zookeeper app

应用程序将等待ZooKeeper集合的进一步通知.使用ZooKeeper CLI zkCli.sh更改指定znode的数据

cd /path/to/zookeeper
bin/zkCli.sh
>>> set /MyFirstZnode Hello

现在,应用程序将打印以下输出并退出.

Hello

setData方法

ZooKeeper类提供setData方法类修改指定znode中附加的数据.setData方法的签名如下:

setData(String path, byte[] data, int version)

  path - Znode路径

  data - 要存储在指定znode路径中的数据

  version - znode的当前版本.每当数据更改时,ZooKeeper会更改znode的版本号.

现在让我们创建一个新的Java应用程序来了解ZooKeeper API的setData功能.创建文件ZKSetData.java.在main方法中,使用ZooKeeperConnector对象创建一个ZooKeeper对象zk.然后,使用指定的路径,新数据和节点版本调用zk对象的setData方法.

  

import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.ZooKeeper;

public class ZkSetData {

    private static ZooKeeperConnector conn;
    private static ZooKeeper zk;

    // Method to update the data in a znode.Similar to getData but without
    // watcher.
    public static void update(String path, byte[] data) throws KeeperException, InterruptedException {
        zk.setData(path, data, zk.exists(path, true).getVersion());
    }

    public static void main(String[] args) {
        String path = "/MyFirstZnode";
        byte[] data = "Success".getBytes();// Assign data witch is to be updated
        try {
            conn = new ZooKeeperConnector();
            zk = conn.connect("localhost");
            update(path, data);// Update znode data to the specified path
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }
}

编译并执行应用程序后,指定的znode的数据将被改变,并且可以使用ZooKeeper CLI zkCli.sh进行检查.

cd /path/to/zookeeper
bin/zkCli.sh
>>> get /MyFirstZnode

getChildren方法

ZooKeeper类提供getChildren方法来获取特定znode的所有子节点.getChildren方法的签名如下:

getChildren(String path, Watcher watcher)

  path - Znode路径

  watcher - 监视器类型的回调函数.当指定的znode呗删除或znode下的子节点被创建/删除时,ZooKeeper集合将进行通知.这是一次性通知.

import java.util.List;

import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.data.Stat;

public class ZkGetChildren {

    private static ZooKeeperConnector conn;
    private static ZooKeeper zk;

    // Method to check existence of znode and its status,if znode is avalide.
    public static Stat znodeExists(String path) throws KeeperException, InterruptedException {
        return zk.exists(path, true);
    }

    public static void main(String[] args) {
        String path = "/MyFirstZnode";// Assign path to the znode
        try {
            conn = new ZooKeeperConnector();
            zk = conn.connect("localhost");
            Stat stat = znodeExists(path);
            if (stat != null) {
                // "getChildren" method -get all the children of znode.It has
                // two args,path and watch
                List<String> children = zk.getChildren(path, false);
                for (int i = 0; i < children.size(); i++) {
                    System.out.println(children.get(i));// Print children's
                }

            } else {
                System.out.println("Node does not exists");
            }
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }
}

在运行程序之前,让我们使用ZooKeeper CLI zkCli.sh为/MyFirstZnode创建两个子节点

cd /path/to/zookeeper
bin/zkCli.sh
>>> create /MyFirstZnode/MyFirstSubNode Hi
>>> create /MyFirstZnode/MySecondSubNode Hi

现在,编译和运行程序将输出上面创建的znode.

MyFirstSubNode
MySecondSubNode

删除Znode

ZooKeeper类提供了delete方法来删除指定的znode.delete的方法的签名如下:

delete(String path, int version)

  path - Znode路径

  version - znode的当前版本

让我们创建一个新的Java应用程序来了解ZooKeeper API的delete功能.创建文件ZKDelete.java.在main方法中,使用ZooKeeperConnectord对象创建一个ZooKepper对象zk.然后,使用指定的路径和版本号调用zk对象的delete方法.

删除znode的完整程序代码如下:

import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.ZooKeeper;

public class ZkDelete {

    private static ZooKeeperConnector conn;
    private static ZooKeeper zk;
    
    //Method to check existence of znode and its status,is znode is avalide.
    public static void delete(String path) throws KeeperException,InterruptedException{
        zk.delete(path, zk.exists(path, true).getVersion());
    }
    public static void main(String[] args) throws InterruptedException,KeeperException{
        String path = "/MyFirstZnode";//Assign path to the znode
        try {
            conn = new ZooKeeperConnector();
            zk = conn.connect("localhost");
            delete(path);//delete the node with the specified path
        }catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }
}

 

  

posted @ 2019-01-29 10:04  斯然  阅读(282)  评论(0)    收藏  举报