在有curator这个框架之前的时候,然后zookeeper怎么去实现分布式锁,就是利用刚才的那种方案,就是可以去实现,你会有各种各样的疑问,你刚才讲的设计是得先get一下,你不如直接create,因为创建性能还不是那么高的,其实你有各种各样的疑问你得去了解他,你要知道怎么做才能快,你要为性能考虑才能那样去做,之前这块也说了,我们往上走一走吧,很多介绍的东西,你当时有一个大体的概念,但是没有一个很详细的概念,刚才在这里为什么那么去说,就是他的数据基本上是存在内存中的,就是他的一些视图模型,单一视图,都是在内存中的,所以说,在JMater百分百读的场景下,并发可以达到这个,12到13万,你想想吧,所以get的性能是很高的,我一个client端,只要网络没有太大的问题,没有延迟的情况下,get一下马上就能得到反馈,这个效率是非常高的,所以之前我先get一下有没有,你不能get都不get就直接create,等着那块就抛异常了,等着报异常就不好,一般我们不那么去做,就是让性能能更好,都是先去get一下,先去内存里去取,看有没有这条数据,然后再决定到底要不要create,极少量的情况下会发生两个同时get,这个时候创建点肯定有一个先后顺序的,肯定是一个成功,一个失败的,这就是zookeeper怎么去实现分布式这块

然后再往下看,还是要看这个API,其实倒不如直接讲Curator框架,如果不讲这些东西,你直接拿去用的话,面试的时候是很吃亏的,zookeeper怎么去实现分布式锁的,你得讲明白是用临时节点,为什么啊,因为临时节点效率也高,第二点我什么要用get啊,因为zookeeper是有这么一个特性,数据是存在内存中的,get的性能是非常高的,所以说我这么去做,是有理由有依据的,然后咱们再去看一下API,这块要说的一点,咱们是不允许递归创建节点的,你父节点没有创建的情况下是不允许创建子节点的,咱们可以试一试
我们先ls /一下

我把testRoot删掉, rmr /testRoot

然后ls /,当前只有一个zookeeper节点,不允许递归创建节点,父节点不存在的情况下是不允许创建节点的,它是不允许支持序列化框架的,比如我们能不能做这么一件事,user的key就换一个主键ID,value就放一个user对象,或者就一个JAVA对象,这个zookeeper是不支持的,以后它是不支持序列化的,你可以去使用一些第三方的序列化框架,比如Hessian,Kryo序列号框架,就是这些序列号框架,Kryo框架的性能也是非常好的,包括dubbo中也是采用了一种方式,第三个参数是一个权限节点,模模糊糊不知道是什么概念,Ids它是一个API,它是一个静态的,然后他有一个OPEN_ACL_UNSAFE,开放权限即可,这个表示开放权限,后期有一些参数,基本上我从来没有关注过,包括很多API封装的时候,第三方框架就写死了,一般在权限没有太高要求的情况下是没有必要关注的,你就不用费这个事去关注了,相关的问题我们通过网络,不会考虑太详细,只不过是他提供的功能是这样,这个不用关注,然后最后一个是创建节点类型,有4种类型,有持久化的,有持久化顺序的,有个先后顺序,当然会有个什么问题,你可能调一个方法,一个client端C1,现在10个节点,那你这10个节点要有顺序,可能网络走到这个时候,第一个创建可能绕了一圈,第二个可能是没有先后顺序的,如果你有顺序的话你就可以去看看,你这个zookeeper要做一个队列,你可以create一个sequential,就是你要那他做一个队列的一个事,其实很多技术可以提供一个解决方案,就是Redis有一个list类型,它是有一些附加的功能,只不过这种实现起来会比较难,你要抓住最核心的作用是干什么的,然后你辅助的功能,很简单的情况下你可以去用,我们不用消息队列,你想实现基于内存的,很多问题你自己可以去解决,两种解决你可以自己去做,包括这个zookeeper也一样,他想实现一个队列,他可以去提供这个接口,一般有没有人这么去做呢,这是我强调的一个问题,他不仅仅能实现一点,我只是大概提一下,然后往下走,还有一种是异步的方式,节点也分同步和异步,同步的方式就是我创建完了之后,我发一个请求到zookeeper上,我这边得到一个返回值,这是同步的方式,我的代码肯定是在这一点延迟,创建调API,同步方式,异步呢,代码是直接往下走,我又起了一个额外的线程,去监听zookeeper的返回,这是可以去实现的,这里有一个异步方式

package com.learn.zookeeper.base;import java.util.concurrent.CountDownLatch;import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.Watcher.Event.EventType;
import org.apache.zookeeper.Watcher.Event.KeeperState;
import org.apache.zookeeper.ZooKeeper;/*** 这就是关于zookeeper增删改查操作* 简单的讲一下* 里面有一些特殊的方法* 每一套API* 无论是exist,delete,还是get* 都有两套* 一种是同步的方式* 一种是回调的方式* 然后基本上去操作API呢* 会有一些限制* 比如说不能递归的去创建啊* 不能递归的去删除* 去掉getChildren方法的时候* 十六进制JAVA怎么表示来着* 有点不记得了* 用byte[]字节数组* get只能取得一层* 你不能把下面的节点也取得到* 有很多限制* 这是关于咱们zookeeper的API* * @author Leon.Sun**/
public class ZookeeperBase {static final String CONNECT_ADDR = "59.110.138.145:2181";
//  static final String CONNECT_ADDR = "192.168.80.88:2181,192.168.80.87:2181,192.168.80.86:2181";static final int SESSION_OUTTIME = 2000;//ms /** 信号量,阻塞程序执行,用于等待zookeeper连接成功,发送成功信号 */static final CountDownLatch connectedSemaphore = new CountDownLatch(1);public static void main(String[] args) throws Exception{ZooKeeper zk = new ZooKeeper(CONNECT_ADDR, SESSION_OUTTIME, new Watcher(){@Overridepublic void process(WatchedEvent event) {KeeperState keeperState = event.getState();EventType eventType = event.getType();//如果是建立连接if(KeeperState.SyncConnected == keeperState){if(EventType.None == eventType){try {System.out.println("开始连接.....");Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("zk 建立连接");//如果建立连接成功,则发送信号量,让后续阻塞程序向下执行connectedSemaphore.countDown();}}}});//进行阻塞connectedSemaphore.await();System.out.println("执行啦..");Thread.sleep(5000);//创建父节点
//      String ret = zk.create("/testRoot", "testRoot11".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
//      System.out.println(ret);//创建子节点/*** 现在我想又一次创建* 肯定是没有/testRoot这个节点的* 就像创建/children* 行吗* 肯定是不行的* 咱们运行一下吧* KeeperException$NoNodeException: KeeperErrorCode = NoNode for /testRoot/children* 就是你没有父节点你就想创建子节点* zookeeper原生的API是不支持的* 怎么去实现的* 你得先判断一下* 先来个if再来个else* 其实Curator的框架怎么去封装的呢* 无非就是先if判断当前* 如果路径很长的话* 还有个aaa* 还有个ccc* 一层一层的去判断* 先判断children他的上一级有没有* 再判断ccc他的上一级有没有* aaa他的上一级有没有* 其实就是这个意思* 只要他的上一级没有我就抛一个异常* 然后像Curator框架* 如果不存在我就一层一层的创建* 如果/testRoot这个不存在就创建出来* 如果/aaa这个不存在就创建出来* /ccc这个不存在我还得创建出来* 他有个ifparentexist的方法* 不允许去创建没有的父节点的* 咱们把刚才的事说一下* 把刚才的事说一下* 不允许递归创建节点* * */
//      String ret = zk.create("/testRoot/aaa/ccc/children", "children data".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);/*** 如果你这么去创建是不行的* 咱们ls /一下* 我现在根节点下只有一个zookeeper* 然后是没有testRoot的* 创建它会返回一个什么值呢* 它是抛了一个异常* KeeperException$NoNodeException: KeeperErrorCode = NoNode for /testRoot/children* 在原生的zookeeper* 它是不允许你递归的去创建节点的* 以后的Curator框架* 会有一个ifparentexist* 它会帮你把父节点创建好* 这也是原生API的问题* 其实Curator也是把原生的API进行一个封装* 无非是在判断节点的时候判断一下他上个节点是不是存在* 如果不存在就把他创建好* 如果存在的话就创建节点* 这是第一个问题* 在原生的API中是不允许递归创建节点的*/
//      String ret = zk.create("/testRoot/children", "children data".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);/*** create其实是有CallBack和Object的* 就是每个方法都提供了两套API* 一个是正常的创建同步的创建* 还有个是异步的创建* 异步创建效率有点高* 咱们同步的是一个 * 异步的去删除* 创建成功了* /testRoot* 然后我在下面ls /* 下面就有testRoot这个节点了* 然后接下来进行delete* 这个Delete操作其实也很简单* * 这里先注释* 否则再创建就会报exists节点已经存在* * /testRoot这个创建好了以后* 我再去取的时候就有了* dataVersion = 0* 版本号的标识被改了几次* update了几次* * */
//      String ret = zk.create("/testRoot", "testRoot11".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
//      System.out.println(ret);/*** 现在这样去做* 我这里delete一个节点* 其实它这个delte方法也有* zookeeper能存数据的版本号* 比如我们去get /testRoot* dataVersion = 0* 你会发现这个版本号是0* 这里有很多version* 但是我们就看dataVersion* 第一次是0* 比如我修改一下* set /testRoot 2222* 我再去get的时候发现dataVersion改变了 * dataVersion = 1* 如果我在改一下* set /testRoot 5555* dataVersion = 2* 我能取到每一个版本号* 对应的你要delete哪一个版本号的数据* 你要是写-1就是全清空* 就是全删除* 一般我们去做delete节点的话* 现在的testRoot的版本号已经到了2了* * 现在我想去删除* delete一般传了第二个参数-1* 4个参数吗* 然后这里有一个VoidCallback* Object ctx2可以传入一个Callback的参数* 实例化出来VoidCallback这么一个对象* 这个是一个静态的* 它是异步的* * */
//      zk.delete("/testRoot", -1,new VoidCallback() {
//
//          /**
//           * 然后你要去重载一个方法是这个processResult
//           *
//           * 这就是我之前说的一个callback方法
//           * 每一个delete都会存在一个回调
//           *
//           */
//          @Override
//          public void processResult(int rc, String path, Object ctx2) {
//              /**
//               * 我休眠1秒钟
//               */
//              try {
//                  Thread.sleep(1000);
//              } catch (InterruptedException e) {
//                  e.printStackTrace();
//              }
//              /**
//               * 第一个int类型的东西是啥啊
//               * 响应码
//               * 如果是0表示回调成功
//               * 如果是-4表示端口连接
//               * 如果是-110表示指定节点存在
//               * -112表示会话已经过期
//               * callback可能成功可能失败
//               * 能有好多个状态
//               */
//              System.out.println(rc);
//              /**
//               * path表示节点的参数路径是什么
//               *
//               * 第二个参数是path
//               * 当前删除的节点是什么
//               */
//              System.out.println(path);
//              /**
//               * 然后还有一些东西
//               * ctx上下文环境
//               * 还有一个name
//               * 很多回调的参数
//               * 我现在只取了这三个
//               *
//               */
//              System.out.println(ctx2);
//          }
//
//          /**
//           * 这个a是一个Object
//           * 就是传入任何一个参数
//           * 都会回调到ctx2这里
//           * 咱们之前学RocketMQ的事务
//           * 事务的callback里面也会有一个参数
//           * 其实一个道理
//           * 这是一个callback的一个机制
//           * -1是跳过版本检查
//           * 如果不是当前的版本就不删除了
//           * 我数据库可能有一份记录
//           * 当前咱两是不是一个版本号
//           * 如果是的话我做一个check
//           */
//      },"a");System.out.println("继续执行.......");/*** 在这里等待这么长的时间*/
//      Thread.sleep(5000);/*** 我现在直接做一个删除* 成功了以后我们再去get* get /testRoot* Node does not exist: /testRoot* 一般不考虑版本号* 一般用-1* */
//      zk.delete("/testRoot", 2);/*** 其实你也不用休眠了*/
//      Thread.sleep(10000);//获取节点洗信息/*** 接下来看获得节点* ZooKeeper.getData(String path, boolean watch, Stat stat) * watch先不用理会* stat状态呢也不用理会* 因为如果你要讲API的话* 但是不用关注后面两个参数* 其实就是想去获得节点的value值* value值返回的还是一个data类型* testRoot咱们包装成一个String* 基本上就是这个操作* 先讲简单的再讲复杂的* 咱们create /testRoot 1122* 创建成功以后ls /* 看到testRoot了* 咱们现在执行一下看有没有效果* 后面两个参数我们后面会讲* 先不用关注这么复杂的东西* * */
//      byte[] data = zk.getData("/testRoot", false, null);
//      /**
//       * 现在我想获得一堆怎么办
//       *
//       */System.out.println(new String(data));
//
//      /**
//       * 一堆children我想获得的话
//       *
//       */System.out.println(zk.getChildren("/testRoot", false));
//
//      /**
//       * 他返回的是一个String类型的list
//       * ZooKeeper.getChildren(String path, boolean watch)
//       * 第二个参数是watch
//       * 总是有一个watch的东西
//       * 这个东西其实很烦
//       * create /testRoot/a1 1111
//       * create /testRoot/a2 2222
//       * create /testRoot/a5 2222
//       * 现在ls /testRoot下面
//       * [a1, a2, a5]
//       * 你会发现有三个节点三个孩子了
//       * 他相当于一个父亲了
//       * 然后我现在getChildren的时候
//       * 把孩子都给拿出来了
//       * 这是很简单的
//       * 返回的类型已经固定了
//       *
//       */
//      List<String> list = zk.getChildren("/testRoot", false);
//
//      /**
//       * 我就去循环他
//       *
//       */
//      for (String path : list) {
//          /**
//           * 这个path是一个相对的路径
//           * a1,a2,a3
//           * 如果你想取值的话
//           * 你得加上前面的父路径/testRoot
//           * 然后a1,a2,a3
//           * 他取出来的是一个相对的
//           * 我就用之前取的方法
//           *
//           * 我这块就是这样去做的
//           * 我直接循环path
//           * 看path有没有就行了
//           * 你会发现这是没有的
//           * 就是getChildren方法你想做递归呢
//           * 他是只支持直接子节点
//           * 能理解我说的意思吧
//           * 这是肯定的
//           * 原生API就是这么去实现的
//           * 为什么这么去实现呢
//           * 其实也是有他的道理的
//           * 这是关于getChildren方法的
//           *
//           *
//           */
//          System.out.println(path);
//          String realPath = "/testRoot/" + path;
//          /**
//           * realPath这个路径传进去
//           * 得到的结果就是1111,2222,2222这个了
//           * 这个应该很简单
//           * 暂时不用去理会这个事
//           * 先把这个简单的API讲完
//           * 再加一层就不行了
//           * 你试一下
//           * 我在a1下面还有一层b1
//           * a1下面有一个b1
//           * create /testRoot/a1/b1 11
//           * 咱们可能就是这种情况了
//           * 我现在能不能把b1也取出来呢
//           *
//           *
//           */
//          System.out.println(new String(zk.getData(realPath, false, null)));
//      }/*** 修改节点其实也很简单* 修改节点* testRoot原先叫什么名字咱们看一下* get /testRoot* 原先叫1122* 我想给他改成"modify data root"这个* -1就是不检查版本号了* 不管你版本号这个问题了* 修改完了再去取* 就变成modify data root这个了* get /testRoot* 数据就变成modify data root这个了* 这个就相当于update* * */
//      zk.setData("/testRoot", "modify data root".getBytes(), -1);
//      byte[] data = zk.getData("/testRoot", false, null);
//      System.out.println(new String(data));//修改节点的值
//      zk.setData("/testRoot", "modify data root".getBytes(), -1);
//      byte[] data = zk.getData("/testRoot", false, null);
//      System.out.println(new String(data));       //判断节点是否存在/*** exists你可以先判断节点是否已经存在* 比如a2* 打印一下* 它会返回一个布尔类型* 4127,4127,1558515470535,1558515470535,0,0,0,0,4,0,4127* 这个长的字符串不用理会* 就跟cZxid = 0x101b这个有点像了* 来试一下吧* 每次都一样* 我不知道行不行* * 如果你给一个a5* */
//      System.out.println(zk.exists("/testRoot/a1", false));/*** 如果你给一个a8* 我在运行的话* 返回的就是一个Null* null就证明这个节点不存在* 如何去判断是否存在* 现在也把exist这个方法测试OK了* 然后最后还有一个delete* 这个delete就不用说了* 就是想删除一个节点* 既然不支持递归的创建* * get /testRoot* 我现在查的是a2* 那我还得这么去做* get /testRoot/a2* cZxid = 0x1035* a2是这个值也应该存在* * * */System.out.println(zk.exists("/testRoot/a2", false));long k = 0x1035;System.out.println(k);//     删除节点/*** 原生的API只有两个方法* 基本上你找不到递归删除的方法* * */
//      zk.delete("/testRoot/a2", -1);/*** 删除这个就报异常了* KeeperException$NotEmptyException: KeeperErrorCode = Directory not empty for /testRoot* Directory not empty* 这个Directory不是空的* 下面有孩子你就删不了了* 既不支持递归的创建* 也不支持递归的删除* 能理解这个意思吗* 这是最基本的API操作* 让你去了解zookeeper最基本的操作* * */
//      zk.delete("/testRoot", -1);
//      System.out.println(zk.exists("/testRoot/a2", false));zk.close();}}

Zookeeper_原生API操作(二)相关推荐

  1. Zookeeper_原生API操作(一)

    讲了zookeeper的简单的介绍,以及环境搭建,还有zkClient的使用,基本上很简单,作为HelloWorld,今天继续往下走,既然已经把简介和环境搭建完了,然后一会来说说配置,配置也没有什么说 ...

  2. Elastic search入门到集群实战操作详解(原生API操作、springboot整合操作)-step1

    Elastic search入门到集群实战操作详解(原生API操作.springboot整合操作)-step2 https://blog.csdn.net/qq_45441466/article/de ...

  3. IOS7使用原生API进行二维码和条形码的扫描

    使用IOS7原生API进行二维码条形码的扫描 IOS7之前,开发者进行扫码编程时,一般会借助第三方库.常用的是ZBarSDK,IOS7之后,系统的AVMetadataObject类中,为我们提供了解析 ...

  4. Java原生API操作XML

    使用Java操作XML的开源框架比较多,如著名的Dom4J.JDOM等,但个人认为不管你用那个框架都要对JDK原生的API有所了解才能更得心应手的应用.本篇就来简单了解下原生的XML API. JAV ...

  5. 使用苹果原生API进行二维码和条形码的扫描

    最近需要用到二维码的扫描,发现苹果有自己的原生的api,这里简单介绍一下. 首先需要引入AVFoundation.framework 库 在相应的viewController里边引入头文件. #imp ...

  6. IOS7原生API进行二维码条形码的扫描

    2019独角兽企业重金招聘Python工程师标准>>> //需要真机 #import "ViewController.h" #import <AVFound ...

  7. ZooKeeper的API操作(二)(通俗易懂)

    所需要6个jar包,都是解压zookeeper的tar包后里面的. zookeeper-3.4.10.jar    jline-0.094.jar    log4j-1.2.16.jar netty- ...

  8. 【Android 内存优化】Android 原生 API 图片压缩原理 ( Bitmap_compress 方法解析 | Skia 二维图形库 | libjpeg 函数库 | libpng 函数库 )

    文章目录 一. 图片质量压缩方法 二. Skia 二维图形库 三. libjpeg.libpng 函数库引入 在博客 [Android 内存优化]图片文件压缩 ( Android 原生 API 提供的 ...

  9. Apache ZooKeeper - 使用原生的API操作ZK_ACL权限

    文章目录 Pre Code 创建world模式的节点 使用授权模式创建节点 使用授权模式获取节点数据 Pre Apache ZooKeeper - ZK的ACL权限控制( Access Control ...

最新文章

  1. maven 学习笔记2
  2. Android之在笔记本电脑adb devices识别不了oppo A9手机(设备管理器ADB Interface里面有个黄色感叹号)
  3. python创建数据库计算机积极拒绝、无法连接_Python3 请求网页源码 目标计算机积极拒绝,无法连接...
  4. 【软件质量】ISO-9126质量模型
  5. RTX游戏本助你玩转一线游戏 畅快过大年
  6. 【车间调度】基于matlab多层编码遗传算法求解车间调度问题【含Matlab源码 035期】
  7. Win10 PSCAD4.5安装心路历程Mark
  8. SSM框架Filter登录后对权限进行甄别,没有权限不可访问指定页面
  9. 清除windows 远程桌面访问记录 批处理
  10. 基于KNN的离群点检测算法的Matlab版实现
  11. 服务器备案新增网站,已经备案服务器 增加新域名
  12. 130、总结:华为、H3C、锐捷三家交换机配置命令详解
  13. 设备管理器中的usb打印支持有个叹号是什么意思,如何解决?
  14. 讲一下 SVG... 吧
  15. 移动端iOS中input输入框搜索框软键盘出现换行而不是搜索
  16. css布局——定位布局
  17. OpenCV基于Python霍夫圆检测—基于梯度的霍夫圆检测
  18. PLC编程学习日记1
  19. Android基础知识梳理
  20. 木瓜移动:从KOL到内容营销,出海品牌如何争夺流量新战场

热门文章

  1. 进程返回linux系统编程之管道(二):管道读写规则和Pipe Capacity、PIPE_BUF
  2. java类初始化顺序
  3. BIO和NIO的区别
  4. 通用计划明年推出自动驾驶出租车共享服务,可定制化设计车辆
  5. vim 粘贴代码格式
  6. 读取速度贼快的省市区地址库
  7. location 匹配规则 (NGINX)
  8. webservice xsd.exe根据xml生成xsd。然后根据xsd生成java bean
  9. CodeForces 699A Launch of Collider
  10. Quick-Cocos2d-x初学者游戏教程(二) -------------------- Quick内部的代码结构及相应的原理...