读取数据:获取子杰点列表和节点数据
getChildren
客户端可以通过Zookeeper的API来获取一个节点的所有子节点,
List<String> getChildren(String path, boolean watch)
void getChildren(String path, boolean watch, Children2Callback cb, Object ctx)
List<String> getChildren(String path, boolean watch, Stat stat)
List<String> getChildren(String path, Watcher watcher)
void getChildren(String path, Watcher watcher, Children2Callback cb, Object ctx)
void getChildren(String path, Watcher watcher, ChildrenCallback cb, Object ctx)
List<String> getChildren(String path, Watcher watcher, Stat stat)
这里列出7个API包含了同步和异步的接口,
Path:指定数据节点的节点路径,
Watcher:注册watcher,一旦在本次子节点获取之后,子节点列表发生变更的话,那么就会向客户端发送通知,该参数允许传入null
Watch:表明是需要注册一个watcher,如果这个参数是true,那么Zookeeper客户端会自动使用默认watcher,如果是false,表明不需要注册watcher
Cb:注册一个异步回调函数
Ctx:用于传递上下文信息的对象
Stat:指定数据节点的节点状态信息,用法是在接口中传入一个旧的stat变量,该stat变量会在方法执行过程中,被来自服务端响应的新stat对象替换
读取数据和创建节点的类似
同步读取
package com.paic.Spark;
import org.apache.zookeeper.*;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.CountDownLatch;
/**
* Created by Xlucas on 2018/4/13.
*/
public class ZookeeperDemo5 implements Watcher{
private static CountDownLatch connectedSe=new CountDownLatch(1);
private static ZooKeeper zk=null;
public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
String path="/zk-hosts-getChild";
zk=new ZooKeeper("10.25.76.173", 2000, new ZookeeperDemo5());
connectedSe.await();
//创建父节点
zk.create(path,"get1".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
//创建子节点
zk.create(path+"/c1","get2".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
List<String> childrenlist=zk.getChildren(path,true);
System.out.println(childrenlist);
//再次创建路径
zk.create(path+"/c2","get3".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE,CreateMode.EPHEMERAL);
Thread.sleep(Integer.MAX_VALUE);
}
@Override
public void process(WatchedEvent event) {
//监听路径节点下是否有变化,
if(Event.KeeperState.SyncConnected==event.getState()){
if (Event.EventType.None==event.getType()&&null ==event.getPath()){
connectedSe.countDown();
}else if(event.getType()== Event.EventType.NodeChildrenChanged){
try{
System.out.println("getChild"+zk.getChildren(event.getPath(),true));
}catch (Exception e){
}
}
}
}
}
运行结果
[c1]
getChild[c1, c2]
首先创建了一个父节点/zk-hosts-getChild,以及一个子节点/zk-hosts-getChild/c1,然后调用getChildren的同步接口来获取/zk-hosts-getChild节点下的所有子节点,同时在接口调用的时候注册一个watcher,之后,我们继续向/zk-hosts-getChild节点创建节点/zk-hosts-getChild/c2,由于之前我们队/zk-hosts-getChild节点注册了一个watcher,因此一旦此时有子节点被创建,Zookeeper服务端就会向客户端发出一个”子节点变更”的事件通知,于是,客户端在收到这个事件通知之后就可以再次调用getChildren方法来获取新的子节点列表
另外,从输出的结果中我们还可以看到,调用getChildren获取到的节点列表,都是数据节点的相对节点路径,上面我们输出的结果是c1 和c2,事实上,完整的ZNode路径应该是 /zk-hosts-getChild/c1 和/zk-hosts-getChild/c2
异步读取
package com.paic.Spark;
import org.apache.zookeeper.*;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.CountDownLatch;
/**
* Created by Xlucas on 2018/4/13.
*/
public class ZookeeperDemo6 implements Watcher {
private static CountDownLatch connectedSe=new CountDownLatch(1);
private static ZooKeeper zk=null;
public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
String path="/zk-hosts-getChild1";
zk=new ZooKeeper("10.25.76.173", 2000, new ZookeeperDemo6());
connectedSe.await();
//创建父节点
zk.create(path,"get1".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
//创建子节点
zk.create(path+"/c1","get2".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
zk.getChildren(path,true,new GetChildred(),null);
//再次创建路径
zk.create(path+"/c2","get3".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE,CreateMode.EPHEMERAL);
Thread.sleep(Integer.MAX_VALUE);
}
@Override
public void process(WatchedEvent event) {
//监听路径节点下是否有变化,
if(Watcher.Event.KeeperState.SyncConnected==event.getState()){
if (Watcher.Event.EventType.None==event.getType()&&null ==event.getPath()){
connectedSe.countDown();
}else if(event.getType()== Watcher.Event.EventType.NodeChildrenChanged){
try{
System.out.println("getChild"+zk.getChildren(event.getPath(),true));
}catch (Exception e){
}
}
}
}
}
package com.paic.Spark;
import org.apache.zookeeper.AsyncCallback;
import org.apache.zookeeper.data.Stat;
import java.util.List;
/**
* Created by Xlucas on 2018/4/13.
*/
public class GetChildred implements AsyncCallback.Children2Callback {
@Override
public void processResult(int rc, String path, Object ctx, List<String> childred , Stat stat) {
System.out.println("rc: "+rc+" path: "+path+" ctx: "+ctx+" chilred: "+childred+" stat: "+stat);
}
}
运行日志
rc: 0 path: /zk-hosts-getChild1 ctx: null chilred: [c1] stat: 30064778013,30064778013,1523580253136,1523580253136,0,1,0,0,4,1,30064778014
getChild[c1, c2]
我们将子节点列表的获取逻辑进行了异步化,异步接口通常会应用在这样的使用场景中,应用启动的时候,会获取一些配置信息,例如“机器列表”这些配置通常比较大,并且不希望配置的获取影响应用的主流程