Zookeeper使用

1.安装

...................

2.Zookeeper常见命令

①create命令创建节点

create [-s][ -e] path data acl

-s:顺序节点 -e:临时节点 都不加为持久节点 path:节点名称 data节点值 acl权限

②读取节点

ls path

path:表示

命令名称命令命令说明
create(创建节点)create [-s][ -e] path data acl-s:顺序节点 -e:临时节点 都不加为持久节点 path:节点名称 data节点值 acl权限
ls(获取节点信息)ls pathpath:节点路径
get(获取节点数据和属性)get pathpath:节点路径
set(更新节点)set path data [version]version:数据版本号 Zookeeper节点中数据是有版本的概念的(指定版本进行更新的 锁的概念)
delete(删除)

delete path [version]

version:同上 注:如果一个节点有子节点,不能直接删除这个节点,需要先删除这个子节点

 

 

 

 

 

 

 

 

3.java客户单API使用

创建Zookeeper实例来连接Zookeeper服务器

{

        try {
            //await() 阻塞当前进程 当countDown()减1 当count数量为0的时候阻塞才会结束
            CountDownLatch latch = new CountDownLatch(1);
            //connectString:连接字符串 timeout:会话的超时时间,watcher:事件监听机制 canBeReadOnly:只读模式
            //事件监听 zookeeper连接时异步连接,Watcher事件监听 是回调函数 默认的监听
            /*
            new Watcher() {
                //事件监听 zookeeper连接时异步连接,Watcher事件监听 是回调函数
                @Override
                public void process(WatchedEvent watchedEvent) {
                    if (watchedEvent.getState() == Event.KeeperState.SyncConnected){
                        latch.countDown();
                    }
                }
            }
             */
            ZooKeeper zk = new ZooKeeper("127.0.0.1:2181", 1000, watchedEvent -> {
                if (watchedEvent.getState() == Watcher.Event.KeeperState.SyncConnected){
                    latch.countDown();
                }
            });
            latch.await();
            //创建节点 path:节点路径 data 节点值(序列化)acl权限 createMode 节点性质EPHEMERAL(临时)PERSISTENT持久节点
            //EPHEMERAL_SEQUENTIAL(临时顺序) PERSISTENT_SEQUENTIAL(持久顺序)
            //临时节点
            zk.create("/hqz","1".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);

            /*
             @Override
                public void processResult(int i, String s, Object o, String s1) {

                }
             */
            //i result code响应码 0成功 -4客户端服务端断开连接 -110节点不存在 -112会话过期
            // s路径 o
            // ctx上下文
            // s1节点名称
            //持久节点
            //异步 回调函数
            zk.create("/hz","1".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE,CreateMode.PERSISTENT, (i, s, o, s1) -> {
                System.out.println("i:" + i + " s:" + s + " o:" + o + " s1:" + s1);
            },"11");

            //同步获取数据
            Stat stat = new Stat();
            byte[] bytes = zk.getData("/hqz",true,stat);
            System.out.println(new String(bytes));

            //删除先删除子节点
            //同步删除
            zk.delete("/hz",stat.getVersion());
            //异步删除
            //VoidCallBack()
            zk.delete("/hz", stat.getVersion(), (i, s, o) -> {
                System.out.println("i:" + i + " s:" + s + " o:" + o);

            },"22");
            
            //创建节点只能一级一级的创建
            //zk.create("/qz","1".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
            //zk.create("/qz/hqz","1".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
            //zk.create("/qz/hz","1".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);

            //path:节点路径 watch:子节点监听
            List<String> nodes = zk.getChildren("/qz",true);
            nodes.forEach(str-> System.out.println(str));

            /**
             * 注在Zookeeper原生的API中watch监听不能提供反复监听功能
             */
            zk.getChildren("/qz", watchedEvent -> {
                try {
                   List<String> node = zk.getChildren(watchedEvent.getPath(),true);
                   node.forEach(str-> System.out.println("change" + str));
                } catch (KeeperException e) {
                    e.printStackTrace();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });

           // zk.create("/qz/hzq2","1".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);

            //更新节点数据 同步 watch true 数据改变走默认的watch监听
            byte[] b = zk.getData("/qz",true,stat);
            System.out.println("qz1:" + new String(b));
            zk.setData("/qz","2".getBytes(),stat.getVersion());
             b = zk.getData("/qz",true,stat);
            System.out.println("qz1:" + new String(b));

            //异步更新
            //new AsyncCallback.StatCallback() {
            //    @Override
            //    public void processResult(int i, String s, Object o, Stat stat) {

             //   }
            //}
            zk.setData("/qz", "3".getBytes(), stat.getVersion(), (i, s, o, stat1) -> {
                System.out.println("qz:" + "i:" + i + " s" + " o:" + o + " stat1:" + stat1.getVersion());
                try {
                    System.out.println("qz:" + new String (zk.getData("/qz",true,stat)));
                    System.out.println(stat.getVersion());
                } catch (KeeperException e) {
                    e.printStackTrace();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            },"333");


            //检测节点是否存在 同步
            Stat stat1 =  zk.exists("/first", watchedEvent -> {
                System.out.println("节点路径0:" + watchedEvent.getPath());
            });

            zk.delete("/first",stat1.getVersion());
            //异步检测节点是否存在
            zk.exists("/first", watchedEvent -> {

                System.out.println("节点路径1:" + watchedEvent.getPath());

            }, (i, s, o, stat2) -> {

                System.out.println("first:" +"i:" + i + " s:" + s + "o:" + o + "stat2:" + stat2.getVersion());

            },"double");

            //zk.delete("/double1",stat1.getVersion());

            zk.create("/first","1".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);

            zk.getData("/first", false, stat);

            System.out.println("stat:" + stat.getVersion());

           Thread.sleep(10000);

        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException e){
            e.printStackTrace();
        } catch (KeeperException e) {
            e.printStackTrace();
        }

    }

4.zkClient 封装了原生的API,提供了Session超时重连、watch反复注册等功能。

public static void main(String[] args) throws InterruptedException {

        //穿件连接
        //在zkClient中奖ZK连接异步化转换为同步化 connectionTimeout连接超时 SessionTimeOut session超时 默认30000毫秒
        ZkClient zkClient = new ZkClient("127.0.0.1:2181",5000,3000);

        //创建节点 返回节点信息
       // String str = zkClient.create("/zkClientQQ","zkClientQQ", CreateMode.PERSISTENT);
        //System.out.println(str);///zkClient

        //createParents 是否创建父节点 原生API中创建子节点需要先创建父节点才能创建子节点
        //创建的节点内容为null
        //zkClient.createPersistent("/zkClient1/zkClient2",true);

        //删除节点
        //zkClient.delete("/zkClient");

        //删除节点 以及该节点的子节点 原生API删除节点之前必须要先删除其子节点
        //zkClient.deleteRecursive("/zkClient1");


        //List<String> client = zkClient.getChildren("/");
        //client.forEach(s-> System.out.println("client:" + s));

        //获取子节点列表
        //List<String> client1 = zkClient.getChildren("/zkClient1");
        //client1.forEach(s-> System.out.println("client1:" + s));
        /**
         * s:父节点 list子节点路径列表
         * @Override
         * public void handleChildChange(String s, List<String> list) throws Exception {
         * }
         * 监听:新增子节点、更新子节点、删除子节点
         * 若删除主节点:s为主节点的全路径 list为null
         * 可以监听不存在的节点当节点创建的时候list为[]
         *
         */
        /*zkClient.subscribeChildChanges("/zkClient-1", (s, list) -> {
            System.out.println("s:" + s);
            System.out.println("list:" + list);
        });

        String data = zkClient.readData("/zkClient");
        System.out.println("data:" + data);

        Stat stat = new Stat();
        String data1 = zkClient.readData("/zkClient",stat);
        System.out.println("data1:" + data1);
        System.out.println("stat:" + stat.getVersion());

        String data3 = zkClient.readData("/zkClientqq",true);
        System.out.println("data3:" + data3);*/
        /**
         * Exception in thread "main" org.I0Itec.zkclient.exception.ZkMarshallingError: java.io.EOFException
         * at org.I0Itec.zkclient.serialize.SerializableSerializer.deserialize(SerializableSerializer.java:37)
         * 序列化的问题  没有反序列化
         * zkClient添加节点和获取节点数据 会序列化和反反序列化
         *
         *
         */
        //设置反序列化器
        zkClient.setZkSerializer(new MyZkSerializer());
        //zxClient 默认的反序列化器
        //zkClient.setZkSerializer(new SerializableSerializer());

        String b =zkClient.readData("/zkClientQQ");
        System.out.println("b:" + b);

        /**
         * 监听数据改变
         */
        zkClient.subscribeDataChanges("/zkClientQQ", new IZkDataListener() {

            /**
             * s 路径 o 节点内容
             * @param s
             * @param o
             * @throws Exception
             */
            @Override
            public void handleDataChange(String s, Object o) throws Exception {
                System.out.println("Change s:" + s);
                System.out.println("Object o:" + o);
            }

            /**
             * s 路径
             * @param s
             * @throws Exception
             */
            @Override
            public void handleDataDeleted(String s) throws Exception {
                System.out.println("delete s:" + s);
            }
        });

        //写数据
        //zkClient.writeData("/zkClientQQ","9999");

        //expectedVersion版本号
        //zkClient.writeData("/zkClientQQ","8888",1);

        //判断节点是否存在
       boolean flag = zkClient.exists("/zkClientQQ");
        System.out.println(flag);

        Thread.sleep(1000000);
    }

5.curator的简单使用

public static void main(String[] args) throws Exception {

        /**
         * [ˌekspəˈnenʃl]指数 倡导者 例子
         * 默认的重连策略 ExponentialBackoffRetry 参数说明
         * baseSleepTimeMs初始sleep时间
         * maxRetries 最大重试次数
         * maxSleepMs 最大sleep时间
         */
       RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000,3);

        /**
         * sleepMsBetweenRetry sleep时间
         * n重连次数
         * new RetryNTimes(n,sleepMsBetweenRetry);
         * new RetryOneTime(sleepMsBetweenRetry);
         *
         */

        /**
         * 默认的重连策略有4中
         * ExponentialBackoffRetry
         * RetryNTimes
         * RetryOneTime
         * RetryUntilElapsed
         *
         *
         * 定义自定义的重试策略
         * @Override
         * public boolean allowRetry(int i, long l, RetrySleeper retrySleeper) {
         *  return false;
         *  }
         */
        //创建会话
        //CuratorFramework client = CuratorFrameworkFactory.newClient("127.0.0.1:2181", 5000, 3000, retryPolicy);
        //启动
        //client.start();

        //使用fluent模式创建会话
        CuratorFramework client = CuratorFrameworkFactory.builder().connectString("127.0.0.1:2181")
                .sessionTimeoutMs(5000).retryPolicy(retryPolicy).namespace("base").build();

        client.start();

        //创建节点 值为空 节点类型为持久化
        client.create().forPath("/h1");
        //创建带值的节点
        client.create().forPath("/h1","123".getBytes());
        //withMode 指定节点类型
        client.create().withMode(CreateMode.PERSISTENT).forPath("/h3","h3".getBytes());
        //creatingParentContainersIfNeeded 创建父节点 临时节点 注:只有叶子节点为临时节点 非叶子节点为持久节点(Zookeeper特性)
        client.create().creatingParentContainersIfNeeded().withMode(CreateMode.EPHEMERAL).forPath("/h4/h44","h4".getBytes());

        //只能删除叶子节点
        //client.delete().forPath("/h1");
        //删除一个节点并递归删除子节点
        //client.delete().deletingChildrenIfNeeded().forPath("/h4");
        //强制删除一个节点 只要客户端会话有效 会在后台进行持续删除,直到节点删除成功
        //client.delete().guaranteed().forPath("/h4");

        //读取节点的数据
        client.getData().forPath("/h1");

        //读取节点并返回 stat
        Stat stat = new Stat();
        client.getData().storingStatIn(stat).forPath("/h1");

        client.setData().forPath("/h1","h11".getBytes());
        //更新指定版本的数据
        client.setData().withVersion(1).forPath("/h1","h111".getBytes());

        CountDownLatch countDownLatch = new CountDownLatch(1);

        /**
         * inBackground(BackgroundCallback,Executor)
         * 在Zookeeper中所有异步事件都是由 EventThread 这个线程 EventThread的串行处理机制在绝大多数情况下能保证事件处理的顺序性
         * 弊端:一但处理复杂的业务,消耗较长的时间会影响,其它时间的执行
         * curator中可以允许用户传一个线程池Executor,这样就可以把复杂的时间放到一个专门的线程中去处理
         */
        //异步创建
        client.create().creatingParentContainersIfNeeded().withMode(CreateMode.EPHEMERAL).inBackground(new BackgroundCallback() {
            /**
             *
             * @param curatorFramework 客户端实例 例如 响应码:0成功 -4 连接丢失 -110节点存在 -112 session超时
             * @param curatorEvent 服务端类型 getType() 代表本次事件 create delete get_data set_data ....
             * @throws Exception
             */
            @Override
            public void processResult(CuratorFramework curatorFramework, CuratorEvent curatorEvent) throws Exception {
                System.out.println("");
                countDownLatch.countDown();
            }
        }).forPath("/hh","hh".getBytes());

        countDownLatch.await();

        监听
        /**
         *
         * dataIsCompressed 是否进行数据压缩 true 会在NodeCache第一启动的时候从Zookeeper上取出数据存到缓存中去
         *
         */
        NodeCache nodeCache = new NodeCache(client,"/h1",false);
        nodeCache.start();
        nodeCache.getListenable().addListener(new NodeCacheListener() {
            /**
             * 监听节点内容改变 以及节点创建 但是节点删除不会触发
             * @throws Exception
             */
            @Override
            public void nodeChanged() throws Exception {
                //获取数据值
                System.out.println(new String(nodeCache.getCurrentData().getData()));
            }
        });

        ExecutorService executor = Executors.newFixedThreadPool(3);

        /**
         * cacheData:是否把节点内容缓存起来,true时当节点列表变更时,会将节点内容缓存起来
         * dataIsCompressed:
         * executorService:专门用一个线程池来处理事件通知
         *
         */
        PathChildrenCache pathChildrenCache =new PathChildrenCache(client,"/h4",true,true,executor);
        pathChildrenCache.start();
        pathChildrenCache.getListenable().addListener(new PathChildrenCacheListener() {
            /**
             *注:无法对二级子节点进行监听(Zookeeper也是) 例如:能监听/h4/h4 不能监听 /h4/h4/h4
             * @param curatorFramework 客户端
             * @param pathChildrenCacheEvent 事件类型 定义了子节点的事件类型 child_added child_updated child_removed
             * @throws Exception
             */
            @Override
            public void childEvent(CuratorFramework curatorFramework, PathChildrenCacheEvent pathChildrenCacheEvent) throws Exception {

                switch (pathChildrenCacheEvent.getType()){
                    case CHILD_ADDED:
                        System.out.println("CHILD_ADDED :" + pathChildrenCacheEvent.getData());
                        break;
                    case CHILD_REMOVED:
                        System.out.println("CHILD_REMOVED :" + pathChildrenCacheEvent.getData());
                        break;
                    case CHILD_UPDATED:
                        System.out.println("CHILD_UPDATED :" + pathChildrenCacheEvent.getData());
                        break;
                }
            }
        });
    }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值