ZooKeeper Watcher代码实例

ZooKeeper Watcher代码实例

主要的相关类和接口

Executor 实现了Wathcer接口、Runnable接口、DataMonitorListener接口。

通过connectString 监视ZooKeeper的一个ZNode。

当ZNode发生事件变化时,通过process(WatchedEvent event)方法调用DataMonitor的process(WatchedEvent event)方法。

DataMonitor实现了Wathcer接口和StatCallback接口。

DataMonitor处理ZNode发生变化时的process,以及处理StatCallback的回调方法。

Watcher接口

Watcher接口定义了process(WatchedEvent event) 方法,以及定义了接口Event。

接口Event中定义了KeeperState和EventType。

WatchedEvent

WatchedEvent由KeeperState、EventType和path组成。

它代表当前ZooKepper的连接状态,并且提供发生事件的znode路径以及时间类型。

其中KeeperState代表ZooKeeper的连接状态,分别为:

  1. Disconnected
  2. NoSyncConnected
  3. SyncConnected
  4. AuthFailed
  5. ConnectedReadOnly
  6. SaslAuthenticated
  7. Expired

EventType代表node的状态变更,分别为:

  1. None
  2. NodeCreated
  3. NodeDeleted
  4. NodeDataChanged,就算设置重复的数据也会有该事件
  5. NodeChildrenChanged
AsyncCallback接口

StatCallback接口是AsyncCallback的一种。

AsyncCallback一共定义了如下几个CallBack

  1. DataCallback
  2. ACLCallback
  3. ChildrenCallback
  4. StatCallback
  5. StringCallback
  6. VoidCallback
  7. Children2Callback

创建ZooKeeper Session

通过

ZooKeeper(String connectString, int sessionTimeout, Watcher watcher)

就可以创建Zookeeper的一个Session。

A Simple Watch Client 代码实例

过程和原理
  1. 初始化连接到ZooKeeper,并且注册一个监视器W
  2. W在接收到事件后,执行process()方法,根据事件的state()关闭或者重新启动额外的任务进程。
  3. 如果发生事件的znode和注册的znode路径一致,则调用ZooKeeper的exist()方法,然后执行StatCallback这个回调方法。
  4. 在StatCallback的回调方法中,获得znode对应的数据
  5. 如果数据存在,则执行打印出响应的结果
连接到客户端
sh zkCli.sh -server 127.0.0.1:2181 

运行后Executor.main后,

会得到一个WatchEvent,它的state为SyncConnected,type为null。

如果此时set znode 结点的数据,比如:

set /yangqi_test new-data

会得到一个WatchEvent,它的state为SyncConnected,type为NodeDataChanged 。

相应的,删除结点的时候,将获得类型为NodeDeleted 的Event。创建结点的时候为NodeCreated 。

ZooKeeper.exists()

public void exists(final String path, Watcher watcher,
        StatCallback cb, Object ctx)

其中:

interface StatCallback extends AsyncCallback {
    public void processResult(int rc, String path, Object ctx, Stat stat);
}

StatCallback 中只有一个方法processResult(),用于处理exits()方法后的回调。

ZooKeeper.getData()

public byte[] getData(String path, boolean watch, Stat stat)

用于获得指定路径的数据。



1. create

Class:org.apache.zookeeper.ZooKeeper
public String create(String path, byte[] data, List acl, CreateMode createMode) throws KeeperException, InterruptedException
public void create(String path, byte[] data, List acl, CreateMode createMode, AsyncCallback.StringCallback cb, Object ctx)
创建一个给定路径(path)的节点,并给它设置数据(data)和访问控制列表(acl)。ZooKeeper中的节点相对于文件系统中的目录结构,即是”directory”又是”regular file”。第二个create方法是create的异步版本,当创建完成时则调用异步callback。

(1). org.apache.zookeeper.data.ACL

这部分节选说说Zookeeper中的ACL
ZooKeeper通过ACL来对ZNode进行访问控制。ZooKeeper客户端为znode指定ACL列表,ZooKeeper服务器根据ACL列表判定某个请求ZNode的客户端是否有对应操作的权限。
一个ACL对象由schema:ID和Permissions组成。
a). scheme: scheme对应于采用哪种方案来进行权限管理,zookeeper实现了一个pluggable的ACL方案,可以通过扩展scheme,来扩展ACL的机制。zookeeper-3.4.4缺省支持下面几种scheme:
world: 它下面只有一个id, 叫anyone, world:anyone代表任何人,zookeeper中对所有人有权限的结点就是属于world:anyone的
auth: 它不需要id, 只要是通过authentication的user都有权限(zookeeper支持通过kerberos来进行authencation, 也支持username/password形式的authentication)
digest: 它对应的id为username:BASE64(SHA1(password)),它需要先通过username:password形式的authentication
ip: 它对应的id为客户机的IP地址,设置的时候可以设置一个ip段,比如ip:192.168.1.0/16, 表示匹配前16个bit的IP段
super: 在这种scheme情况下,对应的id拥有超级权限,可以做任何事情(cdrwa)
b). perm. ZooKeeper中有5种权限,从低位到高位分别是READ、WRITE、CREATE、DELETE和ADMIN,ACL的Permissions可以是5种权限中的1种或多种,它们的含义是:
* READ: 允许获取该节点的值和列出子节点。
* WRITE: 允许设置该节点的值。
* CREATE: 允许创建子节点。
* DELETE: 可以删除子节点。
* ADMIN: 允许为该节点设置权限。

(2). org.apache.zookeeper.CreateMode

org.apache.zookeeper.CreateMode可以设置znode是否为EPHEMERAL或者SEQUENTIAL。可以为下面四种值:
PERSISTENT 持久化目录znode
PERSISTENT_SEQUENTIAL 顺序自动编号的目录znode。这个目录节点是根据当前已存在的节点数递增。
EPHEMERAL 临时目录znode,一旦创建这个znode的客户端和服务器断开,这个节点就会自动删除。临时节点(EPHEMERAL)不能有子节点数据
EPHEMERAL_SEQUENTIAL 临时自动编号znode。

(3). zkCli命令

在zkCli中实现了create的命令封装,可以用户测试和数据管理:
create [-s] [-e] path data acl
其中”-s”表示创建一个顺序自动编号的节点,”-e”表示创建一个临时节点.默认为持久性节点
例如:
创建一个永久节点和临时节点

create  /test null
Created /test
create -e /test0 null
Created /test0

创建一个顺序自动编号的节点,ACL为使用digest(用户名:test 密码:debugo),权限为所有(rwcda)。关于digest的产生,可以参考zookeeper中 DigestAuthenticationProvider.generateDigest(String ipName)方法;通过向此方法指定原始的用户名和密码即可获得”digest”之后的字符串,比如传入”test:test”,将会得 到”test:V28q/NynI4JI3Rk54h0r8O5kMug=”,其内部原理是将”密码”部分进行MD5 + sha1操作.

create -s /test0/test null digest:test:V28q/NynI4JI3Rk54h0r8O5kMug=:rwcda
Ephemerals cannot have children: /test0/test
create -s /test/test null digest:test:V28q/NynI4JI3Rk54h0r8O5kMug=:rwcda
Created /test/test0000000000

创建一个节点,其ACL使用ip(172.19.17.0/24)只具有读权限

create /test/test1 "hello world" ip:172.19.17.0/24:r
Created /test/test1

2. exist

class:org.apache.zookeeper.ZooKeeper
public Stat exists(String path, Watcher watcher) throws KeeperException, InterruptedException
返回某个path的znode是否存在。并设置是否监控这个节点(第二个参数boolean watcher)。当第二个参数为true且这个语句执行成功时,监听器(watcher)就会在成功执行建立节点/删除节点/修改该节点数据时候被触发。
exists(String, Watcher)
重载方法,这里可以指定特定的监听器(watcher)对象。
exists(String, Watcher, AsyncCallback.StatCallback, Object)
exists(String, boolean, AsyncCallback.StatCallback, Object)
exist的异步实现

3. delete

public void delete(String path, int version) throws InterruptedException, KeeperException
删除path对应的znode,version为-1可以匹配任何版本,也就是删除这个节点所有的数据。此外,delete同样存在异步版本。
delete(String path, int version, AsyncCallback.VoidCallback cb, Object ctx)
delete的异步版本。
例如zkCli中删除某个节点:

delete /test/test1

4. getChildren

public List getChildren(String path, boolean watch) throws KeeperException, InterruptedException
获取指定path下所有的子znode,这个方法和exist一样同样可以设置watcher/指定特定的Watcher对象。

5. setData & getData

Stat setData(String path, byte[] data, int version)
当给定path的节点存在时给path设置数据,可以指定这个数据的版本号。如果version为-1则可以匹配任意版本。
void setData(String path, byte[] data, int version, AsyncCallback.StatCallback cb, Object ctx)
setData的异步版本。
byte[] getData(String path, Watcher watcher, Stat stat)
获取这个path对应的znode节点的数据,数据的版本等信息可以通过stat来指定。
void getData(String path, Watcher watcher, AsyncCallback.DataCallback cb, Object ctx)
getData的异步版本。

6. setACL和getACL

Stat setACL(String path, List acl, int version)
给某个znode节点重新设置访问权限,需要注意的是ZooKeeper中的目录节点权限都不具有传递性,父znode节点的权限不能传递给子目录节点。在create中已经介绍了ACL的设置方法,可以设置一系列ACL规则(即指定一系列ACL对象)。
void setACL(String path, List acl, int version, AsyncCallback.StatCallback cb, Object ctx)
setACL的异步版本
List getACL(String path, Stat stat)
返回某个znode节点的ACL对象的列表。
void getACL(String path, Stat stat, AsyncCallback.ACLCallback cb, Object ctx)
getACL的异步版本
例如zkCli中设置某个ACL规则:

[zk: localhost:2181(CONNECTED) 43] setAcl /test world:anyone:r
cZxid = 0xf000500ed
ctime = Wed Sep 24 15:13:29 CST 2014
......
[zk: localhost:2181(CONNECTED) 44] getAcl /test
'world,'anyone
: r

你可能感兴趣的:(Zookeeper)