热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

开发笔记:读《分布式一致性原理》JAVA客户端API操作2

篇首语:本文由编程笔记#小编为大家整理,主要介绍了读《分布式一致性原理》JAVA客户端API操作2相关的知识,希望对你有一定的参考价值。创

篇首语:本文由编程笔记#小编为大家整理,主要介绍了读《分布式一致性原理》JAVA客户端API操作2相关的知识,希望对你有一定的参考价值。




创建节点

通过客户端API来创建一个数据节点,有一下两个接口:


public String create(final String path, byte data[], List acl,
CreateMode createMode)
public void create(final String path, byte data[], List acl,
CreateMode createMode, StringCallback cb, Object ctx)

这两个接口分别是同步和异步的方式创建节点

需要注意的是无论是同步还是异步创建节点,zookeeper都不支持递归创建,即在不存在父节点的情况下创建一个子节点

。另外如果一个节点已经存在了,那么再创建同名节点时会抛出异常:NodeExistException

目前,节点的内容只支持byte[]数组类型,也就是说zookeeper不负责对象序列化,需要开发者自己讲内容进行序列化与反序列化。

对已字符串直接调用getByte就行。对于其他复杂对象,可以使用序列化工具来进行。

 

关于权限控制,如果你的应用场景中没有复杂的权限要求,那么直接调用I Ids.OPEN_ACL_UNSAFE,这表明之后对这个节点的任何操作不受权限控制。

使用API创建一个节点:


package znode;
import java.io.IOException;
import java.util.concurrent.CountDownLatch;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooDefs.Ids;
import session.CreateZookeeper;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.Watcher.Event.KeeperState;
public class CreateZnode implements Watcher{
public static CountDownLatch cOnnectedSemaphore= new CountDownLatch(1);

@Override
public void process(WatchedEvent event) {
System.out.println(
"receive watched event:"+event);
if (KeeperState.SyncCOnnected==event.getState()) {
connectedSemaphore.countDown();
}

}
public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
ZooKeeper zooKeeper
= new ZooKeeper("192.168.64.60", 5000, new CreateZookeeper());
connectedSemaphore.await();

String path1
= zooKeeper.create("/zk-test-ephemera-","".getBytes(),Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
System.out.println(
"success create znode:"+path1);

String path2
= zooKeeper.create("/zk-test-ephemera-","".getBytes(),Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
System.out.println(
"success create znode:"+path2);
}
}

上面两个片段使用同步方式创建节点:可以看出创建临时节点返回值就是传入的路劲

使用临时顺序节点返回值会自动加上一个数字


使用异步API创建节点


package znode;
import java.io.IOException;
import java.util.concurrent.CountDownLatch;
import org.apache.zookeeper.AsyncCallback;
import org.apache.zookeeper.AsyncCallback.StringCallback;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooDefs.Ids;
import session.CreateZookeeper;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.Watcher.Event.KeeperState;
public class CreateZnode2 implements Watcher{
public static CountDownLatch cOnnectedSemaphore= new CountDownLatch(1);

@Override
public void process(WatchedEvent event) {
System.out.println(
"receive watched event:"+event);
if (KeeperState.SyncCOnnected==event.getState()) {
connectedSemaphore.countDown();
}

}
public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
ZooKeeper zooKeeper
= new ZooKeeper("192.168.64.60", 5000, new CreateZookeeper());
connectedSemaphore.await();

zooKeeper.create(
"/zk-test-ephemera-","".getBytes(),Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL
,
new IStringCallback(),"I am context");
zooKeeper.create(
"/zk-test-ephemera-","".getBytes(),Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL
,
new IStringCallback(),"I am context");
zooKeeper.create(
"/zk-test-ephemera-","".getBytes(),Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL
,
new IStringCallback(),"I am context");
}
}
class IStringCallback implements AsyncCallback.StringCallback{
@Override
public void processResult(int rc, String path, Object ctx, String name) {
// TODO Auto-generated method stub
System.out.println("create path result: ["+rc+","+path+","+ctx+","+"real path name:"+name+"]");
}

}

 

和同步接口最大的区别在于,节点在创建的过程(包含网络通信和服务端的创建过程),是异步的。而且我们需要注意的是

同步创建过程时我们需要关注接口抛出的异常,而在异步接口中,是不会抛出异常的,所有的异常都会在回调函数中通过Result Code来体现。


删除节点


public void delete(final String path, int version)
public void delete(final String path, int version, VoidCallback cb,
Object ctx)

 

这里列出的两个API是同步和异步的删除接口,API方法的参数说明如表5-5所示。

删除节点和更新节点的操作非常相似,在zookeeper中只允许删除叶子节点。也就是说,如果一个节点存在子节点的话

那么这个节点将无法直接删除,必须先删除其所有子节点。


 

读取数据

读取数据,包含子节点列表的获取和节点数据的获取。

1.getChildren

 


 

首先我们先看看注册watcher。如果zookeeper客户端获取到指定节点的子节点列表后,还需要订阅这个子节点列表的变化通知,

那么就可以通过注册一个Watcher来实现。当有子节点添加或删除时,服务端就会向客户端发送一个NodeChildrenChange的事件。

需要注意的是服务端向客户端发送事件通知时是不包含最新的节点列表的。是需要客户端主动重新获取的。

 

Stat,stat记录一个节点的基本属性信息。创建时的事务ID(cZxid),最后一次修改的事务ID(mZxid)和节点数据内容的长度

dataLength,我们可以将一个旧的stat变量传入,该stat会在执行过程中,被来自服务端响应的心的stat的替换掉。


package getchildren;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.Watcher.Event.EventType;
import org.apache.zookeeper.Watcher.Event.KeeperState;
import org.apache.zookeeper.ZooDefs.Ids;
public class GetChildren1 implements Watcher {

public static CountDownLatch cOnnectedSemaphore= new CountDownLatch(1);

private static ZooKeeper zk = null;
@Override
public void process(WatchedEvent event) {
if (KeeperState.SyncCOnnected==event.getState()) {
if (EventType.None.getIntValue()==event.getState().getIntValue()&&null==event.getPath()) {
connectedSemaphore.countDown();
}
else if (event.getType()==EventType.NodeChildrenChanged) {
try {
System.out.println(
"ReGetChild:"+zk.getChildren(event.getPath(), true));
}
catch (KeeperException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

}

}
public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
String path
= "/zk-book";
zk
= new ZooKeeper("192.168.64.60:2181", 5000, new GetChildren1());
connectedSemaphore.await();

zk.create(path,
"".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
zk.create(path
+"/c1", "".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);

List
children = zk.getChildren(path, true);
System.out.println(children);

zk.create(path
+"/c2", "".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
Thread.sleep(Integer.MAX_VALUE);;
}
}

 

 

 

 

使用异步API获取子节点列表

 


package getchildren;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import org.apache.zookeeper.AsyncCallback;
import org.apache.zookeeper.CreateMode;
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;
import org.apache.zookeeper.Watcher.Event.EventType;
import org.apache.zookeeper.Watcher.Event.KeeperState;
import org.apache.zookeeper.ZooDefs.Ids;
public class GetChildren2 implements Watcher {

public static CountDownLatch cOnnectedSemaphore= new CountDownLatch(1);

private static ZooKeeper zk = null;
@Override
public void process(WatchedEvent event) {
if (KeeperState.SyncCOnnected==event.getState()) {
if (EventType.None.getIntValue()==event.getState().getIntValue()&&null==event.getPath()) {
connectedSemaphore.countDown();
}
else if (event.getType()==EventType.NodeChildrenChanged) {
try {
System.out.println(
"ReGetChild:"+zk.getChildren(event.getPath(), true));
}
catch (KeeperException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

}

}
public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
String path
= "/zk-book";
zk
= new ZooKeeper("192.168.64.60:2181", 5000, new GetChildren2());
connectedSemaphore.await();

zk.create(path,
"".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
zk.create(path
+"/c1", "".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);

zk.getChildren(path,
true, new IChildren2Callback(),"i am context");

zk.create(path
+"/c2", "".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
Thread.sleep(Integer.MAX_VALUE);;
}
}
class IChildren2Callback implements AsyncCallback.Children2Callback{
@Override
public void processResult(int rc, String path, Object ctx, List children, Stat stat) {
// TODO Auto-generated method stub
System.out.println("Get Children znode result: "+rc+","+path+","+ctx+","+children+","+stat);
}

}

 

 


 getData

getData接口和上下文中的getChildren接口的用法相同,Watcher注册后,一旦节点的内容状态发生改变,zookeeper服务端会

向客户端发送一个NodeDataChanged的事件。API返回的结果类型时byte[].

 

使用同步AIP获取数据节点内容


package getdata;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import org.apache.zookeeper.CreateMode;
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;
import org.apache.zookeeper.Watcher.Event.EventType;
import org.apache.zookeeper.Watcher.Event.KeeperState;
import org.apache.zookeeper.ZooDefs.Ids;
import getchildren.GetChildren1;
public class GetData1 implements Watcher {
public static CountDownLatch cOnnectedSemaphore= new CountDownLatch(1);
private static ZooKeeper zk = null;
private static Stat stat = new Stat();

@Override
public void process(WatchedEvent event) {
if (KeeperState.SyncCOnnected==event.getState()) {
if (EventType.None.getIntValue()==event.getState().getIntValue()&&null==event.getPath()) {
connectedSemaphore.countDown();
}
else if (event.getType()==EventType.NodeDataChanged) {
try {
byte[] data = zk.getData(event.getPath(), true, stat);
System.out.println(
new String(data));
}
catch (KeeperException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

}

}
public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
String path
= "/zk-book";
zk
= new ZooKeeper("192.168.64.60:2181", 5000, new GetData1());
connectedSemaphore.await();

zk.create(path,
"123".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
System.out.println(zk.getData(path,
true, stat));

zk.setData(path,
"456".getBytes(), -1);
Thread.sleep(Integer.MAX_VALUE);;
}
}

 

数据内容或是数据版本发生变化,都胡出发服务端的NodeDataChanged通知。

 

异步API获取


package getdata;
import java.io.IOException;
import java.util.concurrent.CountDownLatch;
import org.apache.zookeeper.AsyncCallback;
import org.apache.zookeeper.CreateMode;
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;
import org.apache.zookeeper.Watcher.Event.EventType;
import org.apache.zookeeper.Watcher.Event.KeeperState;
import org.apache.zookeeper.ZooDefs.Ids;
public class GetData2 implements Watcher {
public static CountDownLatch cOnnectedSemaphore= new CountDownLatch(1);
private static ZooKeeper zk = null;
private static Stat stat = new Stat();

@Override
public void process(WatchedEvent event) {
if (KeeperState.SyncCOnnected==event.getState()) {
if (EventType.None.getIntValue()==event.getState().getIntValue()&&null==event.getPath()) {
connectedSemaphore.countDown();
}
else if (event.getType()==EventType.NodeDataChanged) {
zk.getData(event.getPath(),
true, new IDataback(),null);
}

}

}
public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
String path
= "/zk-book";
zk
= new ZooKeeper("192.168.64.60:2181", 5000, new GetData2());
connectedSemaphore.await();

zk.create(path,
"123".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL );
zk.getData(path,
true,new IDataback(),null);

zk.setData(path,
"456".getBytes(), -1);
Thread.sleep(Integer.MAX_VALUE);;
}
}
class IDataback implements AsyncCallback.DataCallback{
@Override
public void processResult(int rc, String path, Object ctx, byte[] data, Stat stat) {
System.out.println(
new String(data));
System.out.println(stat.getCzxid());
System.out.println(stat.getMzxid());
System.out.println(stat.getVersion());

}

}

 



推荐阅读
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • Redis底层数据结构之压缩列表的介绍及实现原理
    本文介绍了Redis底层数据结构之压缩列表的概念、实现原理以及使用场景。压缩列表是Redis为了节约内存而开发的一种顺序数据结构,由特殊编码的连续内存块组成。文章详细解释了压缩列表的构成和各个属性的含义,以及如何通过指针来计算表尾节点的地址。压缩列表适用于列表键和哈希键中只包含少量小整数值和短字符串的情况。通过使用压缩列表,可以有效减少内存占用,提升Redis的性能。 ... [详细]
  • Java中包装类的设计原因以及操作方法
    本文主要介绍了Java中设计包装类的原因以及操作方法。在Java中,除了对象类型,还有八大基本类型,为了将基本类型转换成对象,Java引入了包装类。文章通过介绍包装类的定义和实现,解答了为什么需要包装类的问题,并提供了简单易用的操作方法。通过本文的学习,读者可以更好地理解和应用Java中的包装类。 ... [详细]
  • 大数据Hadoop生态(20)MapReduce框架原理OutputFormat的开发笔记
    本文介绍了大数据Hadoop生态(20)MapReduce框架原理OutputFormat的开发笔记,包括outputFormat接口实现类、自定义outputFormat步骤和案例。案例中将包含nty的日志输出到nty.log文件,其他日志输出到other.log文件。同时提供了一些相关网址供参考。 ... [详细]
  • 本文介绍了Hyperledger Fabric外部链码构建与运行的相关知识,包括在Hyperledger Fabric 2.0版本之前链码构建和运行的困难性,外部构建模式的实现原理以及外部构建和运行API的使用方法。通过本文的介绍,读者可以了解到如何利用外部构建和运行的方式来实现链码的构建和运行,并且不再受限于特定的语言和部署环境。 ... [详细]
  • Android系统移植与调试之如何修改Android设备状态条上音量加减键在横竖屏切换的时候的显示于隐藏
    本文介绍了如何修改Android设备状态条上音量加减键在横竖屏切换时的显示与隐藏。通过修改系统文件system_bar.xml实现了该功能,并分享了解决思路和经验。 ... [详细]
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • 先看官方文档TheJavaTutorialshavebeenwrittenforJDK8.Examplesandpracticesdescribedinthispagedontta ... [详细]
  • 本文介绍了在处理不规则数据时如何使用Python自动提取文本中的时间日期,包括使用dateutil.parser模块统一日期字符串格式和使用datefinder模块提取日期。同时,还介绍了一段使用正则表达式的代码,可以支持中文日期和一些特殊的时间识别,例如'2012年12月12日'、'3小时前'、'在2012/12/13哈哈'等。 ... [详细]
  • 本文介绍了Swing组件的用法,重点讲解了图标接口的定义和创建方法。图标接口用来将图标与各种组件相关联,可以是简单的绘画或使用磁盘上的GIF格式图像。文章详细介绍了图标接口的属性和绘制方法,并给出了一个菱形图标的实现示例。该示例可以配置图标的尺寸、颜色和填充状态。 ... [详细]
  • 本文整理了Java面试中常见的问题及相关概念的解析,包括HashMap中为什么重写equals还要重写hashcode、map的分类和常见情况、final关键字的用法、Synchronized和lock的区别、volatile的介绍、Syncronized锁的作用、构造函数和构造函数重载的概念、方法覆盖和方法重载的区别、反射获取和设置对象私有字段的值的方法、通过反射创建对象的方式以及内部类的详解。 ... [详细]
  • 本文分析了Wince程序内存和存储内存的分布及作用。Wince内存包括系统内存、对象存储和程序内存,其中系统内存占用了一部分SDRAM,而剩下的30M为程序内存和存储内存。对象存储是嵌入式wince操作系统中的一个新概念,常用于消费电子设备中。此外,文章还介绍了主电源和后备电池在操作系统中的作用。 ... [详细]
  • 1简介本文结合数字信号处理课程和Matlab程序设计课程的相关知识,给出了基于Matlab的音乐播放器的总体设计方案,介绍了播放器主要模块的功能,设计与实现方法.我们将该设 ... [详细]
author-avatar
WLII庾斌_787
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有