zookeeper api——迹忆客-ag捕鱼王app官网
zookeeper 具有针对 java 和 c 的官方 api 绑定。zookeeper 社区为大多数语言(.net、python 等)提供了非官方 api。 使用 zookeeper api,应用程序可以连接、交互、操作数据、协调并最终断开与 zookeeper 整体的连接。
zookeeper api 具有丰富的功能集,可以以简单且安全的方式获得 zookeeper 集合体的所有功能。 zookeeper api 提供同步和异步方法。
zookeeper ensemble 和 zookeeper api 在各个方面都完全互补,并以极大的方式使开发人员受益。 让我们在本章中讨论 java 绑定。
zookeeper api 基础知识
与 zookeeper ensemble 交互的应用程序称为 zookeeper client 或简称为 client。
znode 是 zookeeper ensemble 的核心组件,zookeeper api 提供了一小组方法来使用 zookeeper ensemble 操作 znode 的所有细节。
客户端应该按照下面给出的步骤与 zookeeper ensemble 进行清晰干净的交互。
- 连接到 zookeeper 整体。 zookeeper ensemble 为客户端分配一个 session id。
- 定期向服务器发送心跳。 否则,zookeeper ensemble 会使 session 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 ensemble
zookeeper 类通过其构造函数提供连接功能。 构造函数的签名如下
zookeeper(string connectionstring, int sessiontimeout, watcher watcher)
- connectionstring - zookeeper 集成主机。
- sessiontimeout - 以毫秒为单位的会话超时。
- watcher - 一个实现“watcher”接口的对象。 zookeeper ensemble 通过
watcher
对象返回连接状态。
让我们创建一个新的辅助类 zookeeperconnection
并添加一个方法 connect
。 connect
方法创建一个 zookeeper 对象,连接到 zookeeper 集合体,然后返回该对象。
这里 countdownlatch
用于停止(等待)主进程,直到客户端与 zookeeper 集合体连接。
zookeeper ensemble 通过 watcher 回调回复连接状态。 一旦客户端连接到 zookeeper 集成,就会调用 watcher 回调,并且 watcher 回调会调用 countdownlatch
的 countdown
方法来释放锁,在主进程中等待。
下面是连接 zookeeper 整体的完整代码。
zookeeperconnection.java
// import java classes import java.io.ioexception; import java.util.concurrent.countdownlatch; // import zookeeper classes import org.apache.zookeeper.keeperexception; import org.apache.zookeeper.watchedevent; import org.apache.zookeeper.watcher; import org.apache.zookeeper.watcher.event.keeperstate; import org.apache.zookeeper.zookeeper; import org.apache.zookeeper.asynccallback.statcallback; import org.apache.zookeeper.keeperexception.code; import org.apache.zookeeper.data.stat; public class zookeeperconnection { // declare zookeeper instance to access zookeeper ensemble private zookeeper zoo; final countdownlatch connectedsignal = new countdownlatch(1); // method to connect zookeeper ensemble. public zookeeper connect(string host) throws ioexception,interruptedexception { zoo = new zookeeper(host,5000,new watcher() { public void process(watchedevent we) { if (we.getstate() == keeperstate.syncconnected) { connectedsignal.countdown(); } } }); connectedsignal.await(); return zoo; } // method to disconnect from zookeeper server public void close() throws interruptedexception { zoo.close(); } }
保存上面的代码,它将在下一节中用于连接 zookeeper 集合体。
创建一个 znode
zookeeper 类提供了创建方法来在 zookeeper 集合中创建一个新的 znode。 创建方法的签名如下
create(string path, byte[] data, list acl, createmode createmode)
- path - znode 路径。 例如,/myapp1、/myapp2、/myapp1/mydata1、myapp2/mydata1/myanothersubdata
- data - 要存储在指定 znode 路径中的数据
- acl - 要创建的节点的访问控制列表。 zookeeper api 提供了一个静态接口 zoodefs.ids 来获取一些基本的 acl 列表。 例如,
zoodefs.ids.open_acl_unsafe
返回打开的 znode 的 acl 列表。 - createmode - 节点的类型,可以是临时的,顺序的,或者两者兼而有之。 这是一个枚举。
让我们创建一个新的 java 应用程序来检查 zookeeper api 的创建功能。 创建文件 zkcreate.java。 在 main
方法中,创建一个 zookeeperconnection
类型的对象并调用 connect
方法连接到 zookeeper 集合体。
connect
方法将返回 zookeeper 对象 zk。 现在,使用自定义路径和数据调用 zk 对象的创建方法。
创建 znode 的完整程序代码如下
zkcreate.java
import java.io.ioexception; import org.apache.zookeeper.watchedevent; import org.apache.zookeeper.watcher; import org.apache.zookeeper.watcher.event.keeperstate; import org.apache.zookeeper.zookeeper; import org.apache.zookeeper.keeperexception; import org.apache.zookeeper.createmode; import org.apache.zookeeper.zoodefs; public class zkcreate { // create static instance for zookeeper class. private static zookeeper zk; // create static instance for zookeeperconnection class. private static zookeeperconnection conn; // method to create znode in zookeeper ensemble public static void create(string path, byte[] data) throws keeperexception,interruptedexception { zk.create(path, data, zoodefs.ids.open_acl_unsafe, createmode.persistent); } public static void main(string[] args) { // znode path string path = "/myfirstznode"; // assign path to znode // data in byte array byte[] data = "my first zookeeper app”.getbytes(); // declare data try { conn = new zookeeperconnection(); zk = conn.connect("localhost"); create(path, data); // create the data to the specified path conn.close(); } catch (exception e) { system.out.println(e.getmessage()); //catch error message } } }
编译和执行应用程序后,将在 zookeeper 集合中创建具有指定数据的 znode。 我们可以使用 zookeeper cli zkcli.sh 检查它。
$ cd /path/to/zookeeper
$ bin/zkcli.sh
>>> get /myfirstznode
exists——检查 znode 是否存在
zookeeper 类提供了 exists
方法来检查 znode 是否存在。 如果指定的 znode 存在,它返回 znode 的元数据。 存在方法的签名如下
exists(string path, boolean watcher)
- path - znode 路径
- watcher - 指定是否监视指定 znode 的布尔值
让我们创建一个新的 java 应用程序来检查 zookeeper api 的“exists”功能。 创建一个文件“zkexists.java”。 在 main
方法中,使用 zookeeperconnection
对象创建 zookeeper
对象“zk”。 然后,用自定义的 path
调用“zk”对象的 exists
方法。 完整代码如下:
zkexists.java
import java.io.ioexception; import org.apache.zookeeper.zookeeper; import org.apache.zookeeper.keeperexception; import org.apache.zookeeper.watchedevent; import org.apache.zookeeper.watcher; import org.apache.zookeeper.watcher.event.keeperstate; import org.apache.zookeeper.data.stat; public class zkexists { private static zookeeper zk; private static zookeeperconnection conn; // method to check existence of znode and its status, if znode is available. public static stat znode_exists(string path) throws keeperexception,interruptedexception { return zk.exists(path, true); } public static void main(string[] args) throws interruptedexception,keeperexception { string path = "/myfirstznode"; // assign znode to the specified path try { conn = new zookeeperconnection(); zk = conn.connect("localhost"); stat stat = znode_exists(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()); // catches error messages } } }
编译并执行应用程序后,我们将获得以下输出。
node exists and the node version is 1.
getdata 方法
zookeeper 类提供了 getdata
方法来获取附加在指定 znode 中的数据及其状态。 getdata
方法的签名如下
getdata(string path, watcher watcher, stat stat)
- path - znode 路径。
- watcher - watcher 类型的回调函数。 当指定 znode 的数据发生变化时,zookeeper ensemble 将通过 watcher 回调通知。 这是一次性通知。
- stat - 返回 znode 的元数据。
让我们创建一个新的 java 应用程序来了解 zookeeper api 的 getdata
功能。 创建文件 zkgetdata.java。 在 main
方法中,使用 zookeeperconnection
对象创建 zookeeper
对象 zk。 然后,使用自定义路径调用 zk 对象的 getdata
方法。
这是从指定节点获取数据的完整程序代码
zkgetdata.java
import java.io.ioexception; import java.util.concurrent.countdownlatch; import org.apache.zookeeper.zookeeper; import org.apache.zookeeper.keeperexception; import org.apache.zookeeper.watchedevent; import org.apache.zookeeper.watcher; import org.apache.zookeeper.watcher.event.keeperstate; import org.apache.zookeeper.data.stat; public class zkgetdata { private static zookeeper zk; private static zookeeperconnection conn; public static stat znode_exists(string path) throws keeperexception,interruptedexception { return zk.exists(path,true); } public static void main(string[] args) throws interruptedexception, keeperexception { string path = "/myfirstznode"; final countdownlatch connectedsignal = new countdownlatch(1); try { conn = new zookeeperconnection(); zk = conn.connect("localhost"); stat stat = znode_exists(path); if(stat != null) { byte[] b = zk.getdata(path, new watcher() { public void process(watchedevent we) { if (we.gettype() == event.eventtype.none) { switch(we.getstate()) { case expired: connectedsignal.countdown(); break; } } else { string path = "/myfirstznode"; try { byte[] bn = zk.getdata(path, false, null); string data = new string(bn, "utf-8"); system.out.println(data); connectedsignal.countdown(); } catch(exception ex) { system.out.println(ex.getmessage()); } } } }, null); string data = new string(b, "utf-8"); system.out.println(data); connectedsignal.await(); } else { system.out.println("node does not exists"); } } catch(exception e) { system.out.println(e.getmessage()); } } }
编译并执行应用程序后,我们将获得以下输出。
my first zookeeper app
应用程序将等待来自 zookeeper ensemble 的进一步通知。 使用 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
方法中,使用 zookeeperconnection
对象创建 zookeeper
对象 zk。 然后,使用指定的路径、新数据和节点版本调用 zk 对象的 setdata
方法。
这是修改附加在指定 znode 中的数据的完整程序代码。
zksetdata.java
import org.apache.zookeeper.zookeeper; import org.apache.zookeeper.keeperexception; import org.apache.zookeeper.watchedevent; import org.apache.zookeeper.watcher; import org.apache.zookeeper.watcher.event.keeperstate; import java.io.ioexception; public class zksetdata { private static zookeeper zk; private static zookeeperconnection conn; // 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) throws interruptedexception,keeperexception { string path= "/myfirstznode"; byte[] data = "success".getbytes(); //assign data which is to be updated. try { conn = new zookeeperconnection(); 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 - “watcher”类型的回调函数。 当指定的 znode 被删除或 znode 下的子节点被创建/删除时,zookeeper ensemble 将发出通知。 这是一次性通知。
zkgetchildren.java
import java.io.ioexception; import java.util.*; import org.apache.zookeeper.zookeeper; import org.apache.zookeeper.keeperexception; import org.apache.zookeeper.watchedevent; import org.apache.zookeeper.watcher; import org.apache.zookeeper.watcher.event.keeperstate; import org.apache.zookeeper.data.stat; public class zkgetchildren { private static zookeeper zk; private static zookeeperconnection conn; // method to check existence of znode and its status, if znode is available. public static stat znode_exists(string path) throws keeperexception,interruptedexception { return zk.exists(path,true); } public static void main(string[] args) throws interruptedexception,keeperexception { string path = "/myfirstznode"; // assign path to the znode try { conn = new zookeeperconnection(); zk = conn.connect("localhost"); stat stat = znode_exists(path); // stat checks the path if(stat!= null) { //“getchildren” method- get all the children of znode.it has two args, path and watch list
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/mysecondsubmode hi
现在,编译运行程序会输出上面创建的znodes。
myfirstsubnode
mysecondsubnode
删除 znode
zookeeper 类提供了 delete
方法来删除指定的 znode。 delete
方法的签名如下
delete(string path, int version)
- path - znode 路径。
- version - znode 的当前版本。
让我们创建一个新的 java 应用程序来了解 zookeeper api 的删除功能。 创建文件 zkdelete.java。 在 main
方法中,使用 zookeeperconnection
对象创建 zookeeper
对象 zk。 然后调用指定节点路径和版本的 zk 对象的 delete
方法。
删除 znode 的完整程序代码如下
zkdelete.java
import org.apache.zookeeper.zookeeper; import org.apache.zookeeper.keeperexception; public class zkdelete { private static zookeeper zk; private static zookeeperconnection conn; // method to check existence of znode and its status, if znode is available. 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 zookeeperconnection(); zk = conn.connect("localhost"); delete(path); //delete the node with the specified path } catch(exception e) { system.out.println(e.getmessage()); // catches error messages } } }