znode
是zooKeeper
集合的核心组件,zookeeper API
提供了一小组方法使用zookeeper
集合来操纵znode
的所有细节。
客户端应该遵循以步骤,与zookeeper
服务器进行清晰和干净的交互。
- 连接到
zookeeper
服务器。zookeeper
服务器为客户端分配会话ID
。 - 定期向服务器发送心跳。否则,
zookeeper
服务器将过期会话ID
,客户端需要重新连
接。 - 只要会话
ID
处于活动状态,就可以获取/设置znode
。 - 所有任务完成后,断开与
zookeeper
服务器的连接。如果客户端长时间不活动,则
zookeeper
服务器将自动断开客户端。
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<exclusions>
<exclusion>
<artifactId>zookeeper</artifactId>
<groupId>org.apache.zookeeper</groupId>
</exclusion>
<exclusion>
<artifactId>log4j</artifactId>
<groupId>log4j</groupId>
</exclusion>
<exclusion>
<artifactId>slf4j-log4j12</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
<exclusion>
<artifactId>slf4j-api</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
<version>0.9</version>
</dependency>
<dependency>
<artifactId>zookeeper</artifactId>
<exclusions>
<exclusion>
<artifactId>log4j</artifactId>
<groupId>log4j</groupId>
</exclusion>
<exclusion>
<artifactId>slf4j-log4j12</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
<groupId>org.apache.zookeeper</groupId>
<version>3.4.10</version>
</dependency>
1、连接到Zookeeper
[zkshell: 0] help
ZooKeeper host:port cmd args
get path [watch]
ls path [watch]
set path data [version]
delquota [-n|-b] path
quit
printwatches on|off
create path data acl
stat path [watch]
listquota path
history
setAcl path acl
getAcl path
sync path
redo cmdno
addauth scheme auth
delete path [version]
deleteall path
setquota -n|-b val path
Zookeeper(String connectionString, int sessionTimeout, watcher watcher)
connectionString
-zookeeper
主机;sessionTimeout
- 会话超时(ms为单位);watcher
- 实现"监听器" 对象。zookeeper
集合通过监视器对象返回连接状态。
public static void main(String[] args) throws IOException, InterruptedException {
// 计数器对象
CountDownLatch countDownLatch = new CountDownLatch(1);
// arg1:服务器的ip和端口
// arg2:客户端与服务器之间的会话超时时间 以毫秒为单位的
// arg3:监视器对象
ZooKeeper zooKeeper=new ZooKeeper("192.168.60.130:2181",5000, new Watcher() {
@Override
public void process(WatchedEvent event) {
if(event.getState()==Event.KeeperState.SyncConnected){
System.out.println("连接创建成功!");
countDownLatch.countDown();
}
}
});
// 主线程阻塞等待连接对象的创建成功
countDownLatch.await();
// 会话编号
System.out.println(zookeeper.getSessionId());
zookeeper.close();
}
2、新增节点
// 同步
create(String path, byte[] data, List<ACL> acl, CreateMode createMode)
// 异步
create(String path, byte[] data, List<ACL> acl, CreateMode createMode,
AsynCallback.StringCallback callBack, Object ctx)
参数 | 解释 |
---|---|
path | znode 路径 |
data | 数据 |
acl | 要创建的节点的访问控制列表。zookeeper API 提供了一个静态接口 ZooDefs.Ids 来获取一些基本的acl 列表。例如,ZooDefs.Ids.OPEN_ACL_UNSAFE 返回打开znode 的acl 列表 |
createMode | 节点的类型,这是一个枚举 |
callBack | 异步回调接口 |
ctx | 传递上下文参数 |
示例:
// 枚举的方式
public static void createTest1() throws Exception{
String str = "node";
String s = zookeeper.create("/node", str.getBytes(),
ZooDefs.Ids.READ_ACL_UNSAFE, CreateMode.PERSISTENT);
System.out.println(s);
}
// 自定义的方式
public static void createTest2() throws Exception{
ArrayList<ACL> acls = new ArrayList<>();
Id id = new Id("ip","192.168.133.133");
acls.add(new ACL(ZooDefs.Perms.ALL,id));
zookeeper.create("/create/node4","node4".getBytes(),acls,CreateMode.PERSISTENT);
}
// auth
public static void createTest3() throws Exception{
zookeeper.addAuthInfo("digest","itcast:12345".getBytes());
zookeeper.create("/node5","node5".getBytes(),
ZooDefs.Ids.CREATOR_ALL_ACL,CreateMode.PERSISTENT);
}
// 自定义的方式
public static void createTest3() throws Exception{
// zookeeper.addAuthInfo("digest","itcast:12345".getBytes());
// zookeeper.create("/node5","node5".getBytes(),
// ZooDefs.Ids.CREATOR_ALL_ACL,CreateMode.PERSISTENT);
zookeeper.addAuthInfo("digest","itcast:12345".getBytes());
List<ACL> acls = new ArrayList<>();
Id id = new Id("auth","itcast");
acls.add(new ACL(ZooDefs.Perms.READ,id));
zookeeper.create("/create/node6","node6".getBytes(),
acls,CreateMode.PERSISTENT);
}
// digest
public static void createTest3() throws Exception{
List<ACL> acls = new ArrayList<>();
Id id = new Id("digest","itcast:qUFSHxJjItUW/93UHFXFVGlvryY=");
acls.add(new ACL(ZooDefs.Perms.READ,id));
zookeeper.create("/create/node7","node7".getBytes(),
acls,CreateMode.PERSISTENT);
}
// 异步
public static void createTest4() throws Exception{
zookeeper.create("/node12", "node12".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT, new AsyncCallback.StringCallback(){
/**
* @param rc 状态,0 则为成功,以下的所有示例都是如此
* @param path 路径
* @param ctx 上下文参数
* @param name 路径
*/
public void processResult(int rc, String path, Object ctx, String name){
System.out.println(rc + " " + path + " " + name + " " + ctx);
}
}, "I am context");
TimeUnit.SECONDS.sleep(1);
System.out.println("结束");
}
3、修改节点
同样也有两种修改方式(异步和同步
)
// 同步
setData(String path, byte[] data, int version)
// 异步
setData(String path, byte[] data, int version, StatCallback callBack, Object ctx)
参数 | 解释 |
---|---|
path | 节点路径 |
data | 数据 |
version | 数据的版本号, -1 代表不使用版本号,乐观锁机制 |
callBack | 异步回调 AsyncCallback.StatCallback ,和之前的回调方法参数不同,这个可以获取节点状态 |
ctx | 传递上下文参数 |
public static void setData1() throws Exception{
// arg1:节点的路径
// arg2:修改的数据
// arg3:数据的版本号 -1 代表版本号不参与更新
Stat stat = zookeeper.setData("/hadoop","hadoop-1".getBytes(),-1);
}
public static void setData2() throws Exception{
zookeeper.setData("/hadoop", "hadoop-1".getBytes(), 3 ,new AsyncCallback.StatCallback(){
@Override
public void processResult(int rc, String path, Object ctx, Stat stat) {
// 讲道理,要判空
System.out.println(rc + " " + path + " " + stat.getVersion() + " " + ctx);
}
}, "I am context");
}
4、删除节点
异步、同步
// 同步
delete(String path, int version)
// 异步
delete(String path, int version, AsyncCallback.VoidCallback callBack, Object ctx)
参数 | 解释 |
---|---|
path | 节点路径 |
version | 版本 |
callBack | 数据的版本号, -1 代表不使用版本号,乐观锁机制 |
ctx | 传递上下文参数 |
public static void deleteData1() throws Exception {
zookeeper.delete("/hadoop", 1);
}
public static void deleteData2() throws Exception {
zookeeper.delete("/hadoop", 1, new AsyncCallback.VoidCallback() {
@Override
public void processResult(int rc, String path, Object ctx) {
System.out.println(rc + " " + path + " " + ctx);
}
}, "I am context");
TimeUnit.SECONDS.sleep(1);
}
5、查看节点
同步、异步
// 同步
getData(String path, boolean watch, Stat stat)
getData(String path, Watcher watcher, Stat stat)
// 异步
getData(String path, boolean watch, DataCallback callBack, Object ctx)
getData(String path, Watcher watcher, DataCallback callBack, Object ctx)
参数 | 解释 |
---|---|
path | 节点路径 |
boolean | 是否使用连接对象中注册的监听器 |
stat | 元数据 |
callBack | 异步回调接口,可以获得状态和数据 |
ctx | 传递上下文参数 |
public static void getData1() throws Exception {
Stat stat = new Stat();
byte[] data = zookeeper.getData("/hadoop", false, stat);
System.out.println(new String(data));
// 判空
System.out.println(stat.getCtime());
}
public static void getData2() throws Exception {
zookeeper.getData("/hadoop", false, new AsyncCallback.DataCallback() {
@Override
public void processResult(int rc, String path, Object ctx, byte[] bytes, Stat stat) {
// 判空
System.out.println(rc + " " + path
+ " " + ctx + " " + new String(bytes) + " " +
stat.getCzxid());
}
}, "I am context");
TimeUnit.SECONDS.sleep(3);
}
6、查看子节点
同步、异步
// 同步
getChildren(String path, boolean watch)
getChildren(String path, Watcher watcher)
getChildren(String path, boolean watch, Stat stat)
getChildren(String path, Watcher watcher, Stat stat)
// 异步
getChildren(String path, boolean watch, ChildrenCallback callBack, Object ctx)
getChildren(String path, Watcher watcher, ChildrenCallback callBack, Object ctx)
getChildren(String path, Watcher watcher, Children2Callback callBack, Object ctx)
getChildren(String path, boolean watch, Children2Callback callBack, Object ctx)
参数 | 解释 |
---|---|
path | 节点路径 |
boolean | |
callBack | 异步回调,可以获取节点列表 |
ctx | 传递上下文参数 |
public static void getChildren_1() throws Exception{
List<String> hadoop = zookeeper.getChildren("/hadoop", false);
hadoop.forEach(System.out::println);
}
public static void getChildren_2() throws Exception {
zookeeper.getChildren("/hadoop", false, new AsyncCallback.ChildrenCallback() {
@Override
public void processResult(int rc, String path, Object ctx, List<String> list) {
list.forEach(System.out::println);
System.out.println(rc + " " + path + " " + ctx);
}
}, "I am children");
TimeUnit.SECONDS.sleep(3);
}
7、检查节点是否存在
同步、异步
// 同步
exists(String path, boolean watch)
exists(String path, Watcher watcher)
// 异步
exists(String path, boolean watch, StatCallback cb, Object ctx)
exists(String path, Watcher watcher, StatCallback cb, Object ctx)
参数 | 解释 |
---|---|
path | 节点路径 |
boolean | |
callBack | 异步回调,可以获取节点列表 |
ctx | 传递上下文参数 |
public static void exists1() throws Exception{
Stat exists = zookeeper.exists("/hadoopx", false);
// 判空
System.out.println(exists.getVersion() + "成功");
}
public static void exists2() throws Exception{
zookeeper.exists("/hadoopx", false, new AsyncCallback.StatCallback() {
@Override
public void processResult(int rc, String path, Object ctx, Stat stat) {
// 判空
System.out.println(rc + " " + path + " " + ctx +" " + stat.getVersion());
}
}, "I am children");
TimeUnit.SECONDS.sleep(1);
}