读《分布式一致性原理》JAVA客户端API操作3
更新数据
客户端可以通过zookeeper的API来更新一个节点的数据内容,有如下两个接口:
public Stat setData(final String path, byte data[], int version)
public void setData(final String path, byte data[], int version,
StatCallback cb, Object ctx)
更新数据的接口较为简单明了。我们重点来看下方法中的version参数。version参数是指定节点的数据版本。表明本次更新是针对指定版本进行的。
《java并发编程实践》一书提到,在现代的绝大数计算机处理器体系架构中,都实现了对CAS指令支持,
通俗的将,CAS的意思是“对于值V,每次更新都会对其值是否是值是否是预期值A,只有符合预期,才会将A原子化的更新为B”。zookeeper中setData接口中的version参数正是由CAS原理演化而来的。
具体来说,假如有个客户端想要进行更新操作,那么肯定会携带上次获取的version值进行更新。如果在这段时间,该数据恰好被其他客户端更新了,那么其数据版本一定也发生了变化,因此肯定与客户端携带的version无法匹配,于是便无法更新成功。可以有效的避免分布式更新的并发问题。
使用同步API更新节点数据内容
package setdata; 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.ZooKeeper;
import org.apache.zookeeper.Watcher.Event.EventType;
import org.apache.zookeeper.Watcher.Event.KeeperState;
import org.apache.zookeeper.ZooDefs.Ids;
import org.apache.zookeeper.data.Stat; import getdata.GetData1; public class SetData1 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();
} } }
public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
String path = "/zk-book";
zk = new ZooKeeper("192.168.64.60:2181", 5000, new SetData1());
connectedSemaphore.await(); zk.create(path, "123".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
Stat stat2 = zk.setData(path, "456".getBytes(), -1); System.out.println(stat.getCzxid()+"---"+stat.getMzxid()+"--"+stat.getVersion());
Thread.sleep(Integer.MAX_VALUE);; } }
在zookeeper中,数据版本都是从0开始的,所以严格来讲-1并不是一个数据版本,它仅仅是一个
标示符,是告诉服务器对最新版本进行更新操作。如果对zookeeper数据节点的更新操作没有原子性要求,那么就可以使用“-1”;
所以用异步的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();
}
}
}
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.setData(path, "456".getBytes(), -1,new IDataback(),"");
Thread.sleep(Integer.MAX_VALUE);; }
} class IDataback implements AsyncCallback.StatCallback{ @Override
public void processResult(int rc, String path, Object ctx, Stat stat) {
if (rc==0) {
System.out.println("SUCCESS");
} } }
检测节点是否存在
客户端可以通过zookeeper的api来检测一个节点
该接口主要用于检测指定节点是否存在,返回值是一个Stat对象。如果在调用接口时注册Watcher的话,
还可以对节点是否存在进行监听,一旦节点被创建被删除或被更新,都会通知客户端。
权限控制
在zookeeper的实际使用中,我们的做法往往是搭建一个共用的zookeeper集群,同一为若干个应用提供服务,在这种情况下,不同的应用往往是不存在共享数据的场景的。因此需要解决不同应用之间的权限问题。
zookeeper提供了多种权限控制模式(Scheme),分别是world,auth,digest,ip和super。
本节中我们主要讲digest模式下是如何进行zookeeper权限控制的。
开发人员如果要使用zookeeper的权限控制功能,需要在zookeeper完成会话创建的时候,给该会话添加相关的权限信息(AuthInfo)。zookeeper客户端提供了相应的API接口来进行权限信息的设置。
该接口的主要作用是为当前的zookeeper会话添加权限信息,之后范式通过该会话对zookeeper服务端进行的任何操作都会带上该权限信息。
使用包含权限信息的zookeeper会话创建数据节点。
package auth; import java.io.IOException;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.ZooDefs.Ids;
import org.apache.zookeeper.ZooKeeper; public class AuthInfo { final static String PATH="/zk-book-auth_test";
public static void main(String[] args) throws IOException, KeeperException, InterruptedException {
ZooKeeper zk = new ZooKeeper("192.168.64.60:2181", 5000, null);
zk.addAuthInfo("digest", "foo:true".getBytes());
zk.create(PATH, "123".getBytes(), Ids.CREATOR_ALL_ACL, CreateMode.EPHEMERAL);
Thread.sleep(Integer.MAX_VALUE);
}
}
使用无权限信息的zookeeper会话访问权限信息的数据节点。
package auth; import java.io.IOException;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.ZooDefs.Ids;
import org.apache.zookeeper.ZooKeeper; public class AuthInfo2 { final static String PATH="/zk-book-auth_test";
public static void main(String[] args) throws IOException, KeeperException, InterruptedException {
ZooKeeper zk = new ZooKeeper("192.168.64.60:2181", 5000, null);
zk.addAuthInfo("digest", "foo:true".getBytes());
zk.create(PATH, "123".getBytes(), Ids.CREATOR_ALL_ACL, CreateMode.EPHEMERAL);
ZooKeeper zk2 = new ZooKeeper("192.168.64.60:2181", 5000, null);
zk2.getData(PATH, false, null);
Thread.sleep(Integer.MAX_VALUE);
}
}
一旦我们对一个数据节点设置了权限信息,那么其他没有权限设置的客户端会话将无法访问该数据节点。
对于删除及诶单(delete)接口而言,其权限控制比较特殊。
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.ZooDefs.Ids;
import org.apache.zookeeper.ZooKeeper;
/**
*
* @ClassName: AuthSample_Delete
* @Description: TODO(删除节点的权限控制)
* @author RongShu
* @date 2017年6月11日 下午8:41:23
*
*/
public class AuthSample_Delete {
final static String PATH = "/zk-book-auth_test";
final static String PATH2 = "/zk-book-auth_test/child";
public static void main(String[] args) throws Exception {
ZooKeeper zookeeper1 = new ZooKeeper("localhost:2181",5000,null);
zookeeper1.addAuthInfo("digest", "foo:true".getBytes());
zookeeper1.create( PATH, "init".getBytes(), Ids.CREATOR_ALL_ACL, CreateMode.PERSISTENT );
zookeeper1.create( PATH2, "init".getBytes(), Ids.CREATOR_ALL_ACL, CreateMode.EPHEMERAL );
try {
ZooKeeper zookeeper2 = new ZooKeeper("localhost:2181",50000,null);
zookeeper2.delete( PATH2, -1 );
} catch ( Exception e ) {
System.out.println( "删除节点失败: " + e.getMessage() );
}
ZooKeeper zookeeper3 = new ZooKeeper("localhost:2181",50000,null);
zookeeper3.addAuthInfo("digest", "foo:true".getBytes());
zookeeper3.delete( PATH2, -1 );
System.out.println( "成功删除节点:" + PATH2 );
ZooKeeper zookeeper4 = new ZooKeeper("localhost:2181",50000,null);
zookeeper4.delete( PATH, -1 );
System.out.println( "成功删除节点:" + PATH );
}
} 输出
删除节点失败: KeeperErrorCode = NoAuth for /zk-book-auth_test/child
成功删除节点:/zk-book-auth_test/child
成功删除节点:/zk-book-auth_test
注意:
当客户端对一个数据节点添加了权限信息后,对于删除操作而言,其作用范围是其子节点,也就是说,当我们对一个数据节点添加权限信息之后,依然可以自由的删除这个节点,但是对于这个节点的子节点,就必须使用相应的权限信息才能够删掉它。
读《分布式一致性原理》JAVA客户端API操作3的更多相关文章
- 读《分布式一致性原理》JAVA客户端API操作2
创建节点 通过客户端API来创建一个数据节点,有一下两个接口: public String create(final String path, byte data[], List<ACL> ...
- 读<分布式一致性原理>初识zookeeper
zookeeper是什么 zookeeper是一个典型的分布式数据一致性的解决方案,分布式应用程序可以基于它实现诸如:数据发布/订阅,负载均衡,命名服务,分布式协调/通知 ,集群管理,Master选举 ...
- 读《分布式一致性原理》JAVA客户端API操作
创建会话 客户端可以通过创建一个Zookeeper实例来连接服务器.4种构造方法如下 ZooKeeper(connectString, sessionTimeout, watcher): ZooKee ...
- 从Paxos到Zookeeper 分布式一致性原理与实践读书心得
一 本书作者介绍 此书名为从Paxos到ZooKeeper分布式一致性原理与实践,作者倪超,阿里巴巴集团高级研发工程师,国家认证系统分析师,毕业于杭州电子科技大学计算机系.2010年加入阿里巴巴中间件 ...
- 《从Paxos到Zookeeper:分布式一致性原理与实践》【PDF】下载
内容简介 Paxos到Zookeeper分布式一致性原理与实践从分布式一致性的理论出发,向读者简要介绍几种典型的分布式一致性协议,以及解决分布式一致性问题的思路,其中重点讲解了Paxos和ZAB协议. ...
- zookeeper的Java客户端API
zookeeper作为一个分布式服务框架,主要用来解决分布式数据一致性问题,对多种语言提供了API.这里主要记录下JAVA客户端API的使用. 1.创建会话 客户端可以通过创建一个ZooKeeper实 ...
- Zookeeper的java客户端API使用方法(五)
前面几篇博文,我们简单的介绍了一下zookeeper,如何安装zookeeper集群,以及如何使用命令行等.这篇博文我们重点来看下Zookeeper的java客户端API使用方式. 创建会话 客户端可 ...
- JAVA客户端API调用memcached两种方式
1. memcached client for java客户端API:memcached client for java 引入jar包:java-memcached-2.6.2.jar package ...
- 我读《从Paxos到zookeeper分布式一致性原理与实践》
从年后拿到这本书开始阅读,到准备系统分析师考试之前,终于读完了一遍,对Zookeeper有了一个全面的认识,整本书从理论到应用再到细节的阐述,内容安排从逻辑性和实用性上都是很优秀的,对全面认识Zook ...
随机推荐
- swift获取图片路径出错
获取图片路径 用以下方式获取 let path = Bundle.main.path(forResource: "ImageName", ofType: "ImageTy ...
- vue中axios的深入使用
如上所示一条简单的请求数据,用到了vue中axios,promise,qs等等 这里我将vue中用到的axios进行了封装方便日后使用 先对工具类进行封装utils/axios.js: // 引入模 ...
- BZOJ2933 [Poi1999]地图【区间DP】
Description 一个人口统计办公室要绘制一张地图.由于技术的原因只能使用少量的颜色.两个有相同或相近人口的区域在地图应用相同的颜色.例如一种颜色k,则A(k) 是相应的数,则有: 在用颜色k的 ...
- BZOJ4547 Hdu5171 小奇的集合 【矩阵快速幂优化递推】
BZOJ4547 Hdu5171 小奇的集合 Description 有一个大小为n的可重集S,小奇每次操作可以加入一个数a+b(a,b均属于S),求k次操作后它可获得的S的和的最大值.(数据保证这个 ...
- TLS支持版本检测
今天有开发同事询问“生产环境的TLS版本是多少”,这个问题还真没太关注过,首先想到的是通过Chrome浏览器的开发者工具查看一下,访问https页面查看如下: 这太概是说使用了TLS1.2,于是截图给 ...
- 每次都要重新编译?太慢!让跨平台的 MSBuild/dotnet build 的 Target 支持差量编译
如果你干预到了项目的编译过程,可能就需要考虑到差量编译了.不然--当你的项目大起来的时候,就会感受到每次都重新编译时,每次重复调试的过程都要进行漫长等待时的绝望和无奈. 如果你正遭遇差量编译失效,每次 ...
- 让一个 csproj 项目指定多个开发框架
可移植类库.共享项目..NET Standard 项目都能够帮我们完成跨多个 .NET SDK 的单一项目开发,但它们的跨 SDK 开发都有些限制.现在,我们又有新的方式能够跨多个 .NET SDK ...
- 三分钟教你同步 Visual Studio Code 设置
简介 Visual Studio Code(以下简称vsCode)现在已经渐渐成为前端开发的主力工具,谁让它这么轻便,功能又这么轻便呢.用vscode Coding的小伙伴们也一定会装很多插件吧. ...
- 【java基础】java中Object对象中的Hashcode方法的作用
以下是关于HashCode的官方文档定义: hashcode方法返回该对象的哈希码值.支持该方法是为哈希表提供一些优点,例如,java.util.Hashtable 提供的哈希表. hashCode ...
- 在Eclipse中导入dtd和xsd文件,使XML自动提示
DTD 类型约束文件 1. Window->Preferences->XML->XML Catalog->User Specified Entries窗口中,选择Add ...