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()); } } }

浙公网安备 33010602011771号