我是靠谱客的博主 舒服店员,这篇文章主要介绍7 ,javaAPI 使用,现在分享给大家,希望可以做个参考。

1 ,使用 idea 创建 maven 项目 :

双击打开 idea - create new Project - maven - next
- 填写 GAV ( G:com.itcast ; A:zkTest ;) - next - finish

2 ,引入 maven 依赖 :

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.itcast</groupId>
    <artifactId>zkTest</artifactId>
    <version>1.0-SNAPSHOT</version>
    
    <!-- 我们需要写的代码从这里开始  -->
    <repositories>
        <repository>
            <id>cloudera</id>
            <url>https://repository.cloudera.com/artifactory/cloudera-repos/</url>
        </repository>
    </repositories>
    <dependencies>
        <dependency>
            <groupId>org.apache.zookeeper</groupId>
            <artifactId>zookeeper</artifactId>
            <version>3.4.5-cdh5.14.0</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
        </dependency>
    </dependencies>
</project>

3 ,建类 :Day01

     右键 java - new - 输入 com.heima.zkTest.Day01 - OK
在这里插入图片描述

4 ,看到 Day01 这个类 :

在这里插入图片描述

5 ,查 – 子节点 : ls /

@Test   //  ls /
public void ls() throws IOException, KeeperException, InterruptedException {
    //  String,int,Watcher
    //  集群地址,超时等待时间(过了这么久还连接不上的话,就不等了),观察者。
    ZooKeeper zk = new ZooKeeper("node01:2181",5000,null);
    List<String> list = zk.getChildren("/", null);
    for (String s : list) {
        System.out.println(s);
    }
    zk.close();
}

6 ,查 – 数据 : get /xyj

@Test   //  get /xyj
public void getXyj() throws IOException, InterruptedException, KeeperException {
    ZooKeeper zk = new ZooKeeper("node01:2181",5000,null);
    byte[] data = zk.getData("/xyj", null, null);
    String str = new String(data);
    System.out.println(str);
    zk.close();
}

7 ,查 – 元数据信息 :

@Test   //  stat
public void getStat() throws IOException, InterruptedException, KeeperException {
    ZooKeeper zk = new ZooKeeper("node01:2181",5000,null);
    Stat stat = new Stat();
    zk.getData("/xyj", null, stat);
    System.out.println("数据版本号:" + stat.getVersion());
    System.out.println("节点创建时候的事务 id :" +stat.getCversion());
    System.out.println("数据长度:" + stat.getDataLength());
    zk.close();
}

8 ,增 : create /a tom

@Test   //  create /a tom
public void create() throws InterruptedException, IOException, KeeperException {
    //  连接
    ZooKeeper zk = new ZooKeeper("node01:2181",5000,null);
    //  创建节点
    if(zk.exists("/a",null)==null){
        // 路径,数据(转码成为字节),节点权限( 我们用开放权限 ),保存方式( 我们选永久保存 )
        String msg=zk.create("/a","tom".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE,CreateMode.PERSISTENT);
        System.out.println("创建成功:"+msg);
    }else{
        System.out.println("节点已经存在,不要重复创建...");
    }
    zk.close();
}

9 ,改 : set /a jerry

@Test   //  set /a jerry
public void setA() throws IOException, InterruptedException, KeeperException {
    ZooKeeper zk = new ZooKeeper("node01:2181",5000,null);
    zk.setData("/a","jerry".getBytes(),-1);
    zk.close();
}

10,删 – 单节点: delete /a

@Test   //  delete /a
public void delete() throws IOException, KeeperException, InterruptedException {
    ZooKeeper zk = new ZooKeeper("node01:2181",5000,null);
    //  节点,版本号( -1 代表最新版本号 )
    zk.delete("/a",-1);
    zk.close();
}

11,删 – 目录 :

     javaAPI 不提供删除目录的操作

12,理论 1 – 版本号 : 元数据中的版本号

  1. 修改和删除都需要用到版本号。
  2. 数据的初始版本号是 0
  3. 每次修改数据,版本号就会 +1
  4. 当使用 javaAPI 修改,或这删除数据的时候,需要写版本号,如果写不对版本号,就无法操作数据。
  5. -1 代表最新版本号,我也不管你现在是什么版本,我就操作你这个数据的最新版本。
  6. 版本号的用途 :并发修改。

13,高级操作 :并发修改 ( 重点 )

  1. 先查出来版本号,然后再修改
public static void main(String[] args) throws Exception {
    ZooKeeper zk = new ZooKeeper("node01:2181",5000,null);
    Stat stat = new Stat();
    zk.getData("/a",null,stat);
    int version = stat.getVersion();
    zk.setData("/a","aa".getBytes(),version);
    zk.close();
}
  1. 修改 12 次,依次修改 :
public static void main(String[] args) throws Exception {
    for (int i = 1; i <=12 ; i++) {
        ZooKeeper zk = new ZooKeeper("node01:2181",5000,null);
        Stat stat = new Stat();
        zk.getData("/a",null,stat);
        int version = stat.getVersion();
        zk.setData("/a","aa".getBytes(),version);
        zk.close();
    }
}
  1. 图示:每次修改操作都依次执行,前一次修改结束了,后一次修改才开始进行
    在这里插入图片描述
  2. 并发修改 :12 个线程一起修改
    结果 :11 个错误。
    结论 :1 个用户修改成功,其他 11 个用户全部失败。
public static void main(String[] args) throws IOException {
    for (int i=0;i<12;i++){
        Thread t = new Thread(new Runnable() {
            public void run() {
                try {
                    ZooKeeper zk = new ZooKeeper("node01:2181",5000,null);
                    Stat stat = new Stat();
                    zk.getData("/a",null,stat);
                    int version = stat.getVersion();
                    zk.setData("/a","aa".getBytes(),version);
                    zk.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
        t.start();
    }
}
  1. 12个线程,分批次修改,每三个线程一组:
public static void main(String[] args) throws Exception {
    for (int i = 1; i <=12 ; i++) {
        final int j=i;
        if(i==4||i==7||i==10){
            Thread.sleep(1000);
        }
        Thread t = new Thread(new Runnable() {
            public void run() {
                try {
                    ZooKeeper zk = new ZooKeeper("node01:2181", 5000, null);
                    Stat stat = new Stat();
                    zk.getData("/a", null, stat);
                    int version = stat.getVersion();
                    zk.setData("/a", "aa".getBytes(), version);
                    System.out.println(j);
                    zk.close();
                } catch (Exception e1) {
                    e1.printStackTrace();
                }
            }
        });
        t.start();
    }
}
  1. 对同一时刻的理解 :版本图
    1 ,用户 1,2,3 就相当于同一时刻在修改
    2 ,在 1,2,3 发出修改操作时,他们看到的版本号都是 0
    3 ,但是 1 率先开始修改操作
    4 ,当 1 号修改完成后,数据的版本号已经变成 1 版本
    5 ,2号,3号,手中拿着的版本号仍然是 0 ,但是数据版本号已经是 1 ,所以 2,3 修改失败。
    6 ,组内不确定性:每个小组中都有一个跑得快的线程,占据主导地位,另外两个跑得慢,至于小组中的哪一个跑得快,是不确定的。
    7 ,时间不确定性:理论上说,线程之间存在竞争激烈的竞争,每个小组会有一个线程获胜,但是有可能修改操作执行的很快,以至于,它执行完后,下一个线程才开始启动,这样的话,一个小组中就有可能修改两次数据。
    在这里插入图片描述
  2. 版本号的作用 :
    锁死数据,有了版本号的存在,同一个时刻,只能有一个线程在操作 zookeeper 数据,其他的线程全部操作失败,从而达到支持并发修改操作的目的。
  3. 版本号 -1 的作用 :
    1 ,忽略其他版本号,修改最新版本。
    2 ,解锁数据,我不管别的线程在干嘛,我就要修改,说什么都不听,我就要改。
  4. 用版本号 -1 做修改操作 :12 个线程全成功,不报错
public static void main(String[] args) throws Exception {
    for (int i = 1; i <=12 ; i++) {
        final int j=i;
        Thread t = new Thread(new Runnable() {
            public void run() {
                try {
                    ZooKeeper zk = new ZooKeeper("node01:2181", 5000, null);
                    zk.setData("/a", "aa".getBytes(), -1);
                    System.out.println(j);
                    zk.close();
                } catch (Exception e1) {
                    e1.printStackTrace();
                }
            }
        });
        t.start();
    }
}

10,结论 :
修改操作,单线程操作的话,就用 -1 版本号。
如果考虑并发安全问题,就要用到自己查询的版本号。

14,理论 2 – 权限 : 创建节点时用到 ( 谁可以访问这个节点 )

@Test   //  set /a jerry
    public void create() throws IOException, InterruptedException, KeeperException {
        ZooKeeper zk = new ZooKeeper("node01:2181",5000,null);
        zk.create("/b","bb".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE,CreateMode.PERSISTENT);
        zk.close();
    }
  1. OPEN_ACL_UNSAFE :开放权限,所有人都可读,可写
  2. CREATOR_ALL_ACL : 只有创建这个节点的用户,才能访问这个节点
  3. READ_ACL_UNSAFE :所有用户都可以读这个节点
    在这里插入图片描述

15,理论 3 – 节点类型 : 创建节点时用到

  1. PERSISTENT :永久节点,创建后就一直存在,zk 重启,节点还在
  2. EPHEMERAL :临时节点,客户端断开后,节点消失 ( 打断点,试试看 )
  3. PERSISTENT_SEQUENTIAL :永久序列节点
  4. EPHEMERAL_SEQUENTIAL :临时序列节点
    在这里插入图片描述

16 ,临时节点测试 : 打断点

  1. 创建临时节点,打断点 ,执行 :
    在这里插入图片描述
  2. 查看这个节点 :看到临时节点
    在这里插入图片描述
  3. 放开 debug :
    在这里插入图片描述
  4. 再次查看 :临时节点消失
    在这里插入图片描述
  5. 作用 :保存临时数据

17 ,序列节点 : 就是一串数字

  1. 创建后,他会在节点名字后面加一串数字,10 个数字。
  2. 再次创建序列节点,又一串数字,并且这个数字是刚才的数字加一。
  3. 重要用途 :同步,锁。
  4. 类型:永久型序列节点,临时型序列节点。
  5. 看图,一看便知 :
    在这里插入图片描述

最后

以上就是舒服店员最近收集整理的关于7 ,javaAPI 使用的全部内容,更多相关7内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(53)

评论列表共有 0 条评论

立即
投稿
返回
顶部