zoukankan      html  css  js  c++  java
  • 使用Java操作Zookeeper

    目录

    一、介绍

    二、zookeeper API

      2.1、导入依赖

      2.2、连接zk集群

      2.3、操作数据操作

    三、zkClient API

      3.1、导入依赖

      3.2、使用示例

    一、介绍

      这里主要记录通过Java调用API来操作Zookeeper集群的数据,对于zookeeper集群的搭建或者命令,可以参考:

      目前接触到的Java操作Zookeeper,有两套API,一套是zookeeper官方提供的(zookeeper),另外一套是封装了官方API的API(zkClient),从描述上来看,就知道,官方的API可能不是那么好用,不然也不会在封装。  

    二、zookeeper API

    2.1、导入依赖

      使用zookeeper官方api的时候,请保证jar包的版本,和zk集群中zk的版本相同

    <!-- https://mvnrepository.com/artifact/org.apache.zookeeper/zookeeper -->
    <dependency>
        <groupId>org.apache.zookeeper</groupId>
        <artifactId>zookeeper</artifactId>
        <version>3.4.7</version>
    </dependency>
    

      

    2.2、连接zk集群

      下面是代码示例,两种形式(分别使用匿名类和Lambda表达式):

    package cn.ganlixin.zk;
    
    import org.apache.zookeeper.KeeperException;
    import org.apache.zookeeper.WatchedEvent;
    import org.apache.zookeeper.Watcher;
    import org.apache.zookeeper.ZooKeeper;
    import org.junit.Test;
    
    import java.io.IOException;
    
    public class ZookeeperDemo {
    
        @Test
        public void connectZkCluster() throws IOException, KeeperException, InterruptedException {
    
            // 构造方法
            // ZooKeeper(String connectString, int sessionTimeout, Watcher watcher)
            
            // 匿名对象形式
            ZooKeeper zooKeeper = new ZooKeeper(
                    "192.168.1.3:2181,192.168.1.4:2181,192.168.1.5:2181",
                    20000,
                    new Watcher() {
                        @Override
                        public void process(WatchedEvent watchedEvent) {
                            // 发生变更的节点路径
                            String path = watchedEvent.getPath();
                            System.out.println("path:" + path);
    
                            // 通知状态
                            Watcher.Event.KeeperState state = watchedEvent.getState();
                            System.out.println("KeeperState:" + state);
    
                            // 事件类型
                            Watcher.Event.EventType type = watchedEvent.getType();
                            System.out.println("EventType:" + type);
                        }
                    }
            );
    
            // 关闭连接
            zooKeeper.close();
    
            // Lamdba形式
            ZooKeeper zk = new ZooKeeper(
                    "192.168.1.3:2181,192.168.1.4:2181,192.168.1.5:2181",
                    20000,
                    watchedEvent -> {
                        // 发生变更的节点路径
                        String path = watchedEvent.getPath();
                        System.out.println("path:" + path);
    
                        // 通知状态
                        Watcher.Event.KeeperState state = watchedEvent.getState();
                        System.out.println("KeeperState:" + state);
    
                        // 事件类型
                        Watcher.Event.EventType type = watchedEvent.getType();
                        System.out.println("EventType:" + type);
                    }
            );
    
            zk.close();
        }
    }
    

      

      运行上面的代码,控制台输出如下(输出了两遍,是因为创建了两次连接)

    path:null
    KeeperState:SyncConnected
    EventType:None
    path:null
    KeeperState:SyncConnected
    EventType:None
    

      

    2.3、操作数据操作

      操作Zk中的数据,方式也很简单,只需要使用创建的zk连接,调用对应的方法即可(方法名与zk命令行中命令相同)

    package cn.ganlixin.zk;
    
    import org.apache.zookeeper.CreateMode;
    import org.apache.zookeeper.KeeperException;
    import org.apache.zookeeper.ZooDefs;
    import org.apache.zookeeper.ZooKeeper;
    import org.apache.zookeeper.data.Stat;
    import org.junit.Test;
    
    import java.io.IOException;
    
    public class ZookeeperDemo {
    
        @Test
        public void manageData() throws KeeperException, InterruptedException, IOException {
    
            // 创建zk连接
            ZooKeeper zk = new ZooKeeper(
                    "192.168.1.3:2181,192.168.1.4:2181,192.168.1.5:2181",
                    20000,
                    null
            );
    
            // 创建节点
            zk.create("/abc", "123".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
    
            // 获取节点数据
            // getData(String path, boolean watch, Stat stat);
            Stat stat = new Stat();
            byte[] data = zk.getData("/abc", false, stat);
            System.out.println(new String(data));       // 数据内容 123
            System.out.println(stat.getDataLength());   // 节点状态(数据长度) 3
    
            // 对/abc进行watch
            zk.getData("/abc",
                    watchedEvent -> {
                        System.out.println("path:" + watchedEvent.getPath());
                        System.out.println("KeeperState:" + watchedEvent.getState());
                        System.out.println("EventType:" + watchedEvent.getType());
                    },
                    null);
    
            // 设置节点数据
            // setData(String path, byte[] data, int version)
            // 指定version为-1,表示不关心版本
            zk.setData("/abc", "456".getBytes(), -1);
    
            // 设置两次,第二次不会触发通知
            zk.setData("/abc", "789".getBytes(), -1);
    
            // 阻塞,以等待通知
            Thread.sleep(1000);
            zk.close();
        }
    }

      上面的程序,运行输出结果如下:

    123
    3
    path:/abc
    KeeperState:SyncConnected
    EventType:NodeDataChanged  

      可以看到,只显示了一次通知,和与预期相符。

    三、zkClient API

      因为Zookeeper API比较复杂,使用并不方便,所以出现了ZkClient,ZkClient对Zookeeper API进行了封装,利用ZkClient可以更加方便地对Zookeeper进行操作。

    3.1、导入依赖

      因为zkClient是对zookeeper的再封装,所以需要注意zkClient中zookeeper的版本与zk集群的版本相同,可以在maven仓库中查看对应关系

    <!-- https://mvnrepository.com/artifact/com.101tec/zkclient -->
    <dependency>
        <groupId>com.101tec</groupId>
        <artifactId>zkclient</artifactId>
        <version>0.10</version>
    </dependency>
    

      

    3.2、使用示例

      下面是个简单的示例:

    package cn.ganlixin.zk;
    
    import org.I0Itec.zkclient.IZkChildListener;
    import org.I0Itec.zkclient.IZkStateListener;
    import org.I0Itec.zkclient.ZkClient;
    import org.apache.zookeeper.CreateMode;
    import org.apache.zookeeper.Watcher;
    import org.junit.Test;
    
    import java.util.List;
    
    public class ZkClientDemo {
    
        @Test
        public void testConn() throws InterruptedException {
            ZkClient zkClient = new ZkClient(
                    "192.168.1.3:2181,192.168.1.4:2181,192.168.1.5:2181",
                    20000
            );
    
            // 创建节点
            zkClient.createPersistent("/abc", "hello");
            zkClient.createEphemeral("/xyz", "world");
            zkClient.create("/opq", "world", CreateMode.EPHEMERAL_SEQUENTIAL);
    
            String data = zkClient.readData("/abc");
            System.out.println(data);
    
            // 监听状态变化
            zkClient.subscribeStateChanges(new IZkStateListener() {
                @Override
                public void handleStateChanged(Watcher.Event.KeeperState keeperState) throws Exception {
                    System.out.println("state:" + keeperState);
                }
    
                @Override
                public void handleNewSession() throws Exception {
                    System.out.println("new session");
                }
    
                @Override
                public void handleSessionEstablishmentError(Throwable throwable) throws Exception {
                    throwable.printStackTrace();
                }
            });
    
            // 监听子节点发生变化
            zkClient.subscribeChildChanges("/", new IZkChildListener() {
                @Override
                public void handleChildChange(String path, List<String> list) throws Exception {
                    System.out.println("watch path:" + path);
                    // 输出所有子节点
                    list.forEach(str -> {
                        System.out.println(str);
                    });
                }
            });
    
            Thread.sleep(100000);
        }
    }
    

      

      

     

  • 相关阅读:
    The Google File System 中文版论文(上)(转载)
    百度技术沙龙(第1期) 2. 豆瓣数据存储实践(转载)
    YunTable开发日记(1) 计划 (转载)
    对SQL说不!NoSQL的数据库技术革命(转载)
    YunTable开发日记(8)聊聊分布式数据库的作用(转载)
    探索Google App Engine背后的奥秘(4) Google App Engine的架构(转载)
    企业中的NoSQL(转载)
    探寻关系数据库和ORM的最佳替代者(转载)
    探索Google App Engine背后的奥秘(3) Google App Engine的简介(转载)
    YunTable开发日记(2) – 前三天的总结 (转载)
  • 原文地址:https://www.cnblogs.com/-beyond/p/10993893.html
Copyright © 2011-2022 走看看