• zookeeper、ZK安装、ZK配置、ZK使用


    -----------------------------目录-----------------------------------

    第一部分:zookeeper简介

    第二部分:zookeeper环境搭建

      1、单机环境

      2、集群环境

    第三部分:zookeeper基本使用

      1、java原生zk客户端api操作

      2、zkClient客户端操作(推荐)

      3、curator客户端操作(推荐)

    第四部分:zookeeper应用场景

    第五部分:zookeeper深入进阶

    第六部分:zookeeper源码分析

    -----------------------------目录-----------------------------------

    第一部分:zookeeper简介

    1、 zookeeper基本概念

    zookeeper是一个开源的分布式协调服务,其设计目标是将那些复杂并且容易出差错的分布式一致性服务封装起来,构成一个高效可靠的原语集,并提供给用户一些简单的接口,zookeeper是一个典型的分布式一致性的解决方案(CP模式),分布式应用程序可以基于它实现数据订阅/发布、负载均衡,命名服务、集群管理、分布式锁和分布式队列等功能。

    2、基本概念

    @1、集群角色

    通常在分布式系统中,构成一个集群中的每一台机器都有自己的角色,典型的是master/slave模式(主备模式),这种情况下能够处理写操作的机器成为master机器,把所有通过一步复制方式获取最新数据并且提供服务的机器为slave机器。
    在zookeeper中没有是用主备模式,引入Leader、Follower、Observer三种角色,在zk集群中所有的机器通过Leader选举来选Leader,Leader服务器为客户端提供读写服务,Follower和Observer都能提供读服务,唯一的区别是Observer不参与Leader选举,不参与写操作的过半写成功。

    @2、会话session

    Session指的是客户端的会话,一个客户端链接是指客户端和服务端之间的一个Tcp长连接,ZK对外服务端口默认为2181,客户端启动的时候会与服务器建立一个TCP连接,从第一次链接建立开始客户端会话的声明周期也开始了,通过链接,客户端能够检测心跳和服务端保持有效会话,也能够想zk服务器发送请求并接受响应,同时还能够通过该链接接受来自服务器的Watch事件通知。

    @3、数据节点znode

    在zk中节点分两类:第一类是指构成集群的机器,我们称为机器节点。第二种是指数据模型中的数据单元,称为数据节点znode。zk的数据存储在内存中,数据模型是树型,有斜杠(/)进行分割路径,就是一个znode,每个znode上都会保存自己的数据内容,同时还会保存一系列属性信息。

    @4、版本

    zk在每个数据节点都会存储数据,每个节点都会维护一个价stat的数据结构,记录了三个数据版本:version(当前版本)、cversion(当前节点子节点的版本),aversion(当前节点的ACL版本) 

    @5、ACL

    Zookeeper采用ACL(Access Control Lists)策略来进行权限控制,定义一下五种权限:

      CREATE:创建子节点权限

      READ:获取节点数据和子节点列表的权限

      WRITE:更新节点数据的权限

      DELETE:删除子节点的权限

      ADMIN:设置节点ACL的权限

    注意的是create和delete两盒权限是针对子节点的权限控制

    第二部分:zookeeper环境搭建

     zookeeper安装有一下三种方式

    1、单机模式:zk只运行在一台服务器上,适用测试环境

    2、集群模式:zk运行在一个集群环境中,适用于线上生产环境

    3、伪集群模式:一台服务器上运行多个zk实例监听不同的端口

    这里的环境搭建适用了两个模式,单机模式和伪集群模式

    一、单机模式(Linux)

    1、下载稳定版本https://zookeeper.apache.org/releases.html

    下面是下载命令(注意版本号),也可以登录上面地址进行本地下载,在上传服务器

    wget https://www.apache.org/dyn/closer.lua/zookeeper/zookeeper-3.6.1/apache-zookeeper-3.6.1-bin.tar.gz
    

    2、解压

    tar -zxvf apache-zookeeper-3.6.1-bin.tar.gz
    

    3、进入apache-zookeeper-3.6.1目录创建data文件,用于持久话数据的文件夹

    cd apache-zookeeper-3.6.1
    
    mkdir data
    

    4、修改配置文件名称

    zk默认读取zoo.cfg文件,提供参考文件zoo_sample.cfg文件。

    cd conf
    cp zoo_sample.cfg zoo.cfg
    

    5、修改zoo.cfg文件中的dataDir属性,定位到刚创建的data文件

    dataDir=/user/apache-zookeeper-3.6.1/data

    6、启动服务

    cd ../bin
    
    ./zkServer.sh start

    上面start 命令为启动,stop为停止,status为查看zk启动状态以及身份

    看到下图提示启动成功:

     二、伪集群模式

        点击--->>> ZK安装、ZK配置、ZK集群部署

    第三部分:zookeeper基本使用

    java代码调用zookeeper原生Api进行增删改查节点以及数据的代码

    一、java调用原生zk客户端

    引入pom文件

            <dependency>
                <groupId>org.apache.zookeeper</groupId>
                <artifactId>zookeeper</artifactId>
                <version>3.4.9</version>
            </dependency>

     1、创建zk的客户端连接

     主要是获取zk对象,并进行操作监听。等同于zk开启客户端命令./zkCli.sh。

     需要注意的是监听类实现Watcher接口,重写process 方法

    package city.albert.api;
    
    import org.apache.zookeeper.WatchedEvent;
    import org.apache.zookeeper.Watcher;
    import org.apache.zookeeper.ZooKeeper;
    
    import java.io.IOException;
    import java.util.concurrent.CountDownLatch;
    
    /**
     * @author niunafei
     * @function
     * @email niunafei0315@163.com
     * @date 2020/7/29  6:39 PM
     */
    public class OpenSession implements Watcher {
    
        /**
         * 应为zk的监听为独立线程,需要保持主线程main方法不会直接结束使用CountDownLatch,设置线程数为1
         */
        private static CountDownLatch countDownLatch = new CountDownLatch(1);
    
        /**
         * 建立会话
         * 客户端创建一个连接链接zk
         *
         * @param args
         */
        public static void main(String[] args) throws IOException, InterruptedException {
    
            ZooKeeper zooKeeper = new ZooKeeper("127.0.0.1:2181", 10000, new OpenSession());
            System.out.println(zooKeeper.getState());
            countDownLatch.await();
        }
    
        /**
         * 处理来自服务器端的watcher
         *
         * @param watchedEvent
         */
        @Override
        public void process(WatchedEvent watchedEvent) {
    
            System.out.println(watchedEvent.toString());
            if (watchedEvent.getState() == Event.KeeperState.SyncConnected) {
                System.out.println("process 执行了。。。");
                countDownLatch.countDown();
            }
        }
    }

    2、创建zk的数据节点

    由于代码篇幅问题,下面先介绍重点代码然后附带测试的源代码~~注意哦!

    类似在客户端中执行: create  /my_persist2  123

    重点代码:

     private static void createZNode(ZooKeeper zooKeeper) throws KeeperException, InterruptedException {
            /**
             * path 创建节点路径
             * data[]  节点值的字节数组
             *  acl  节点权限4中类型
             *       ANYONE_ID_UNSAFE  标识任何人
             *       AUTH_IDS    仅仅这个id才可以设置ACL,他将被客户端验证ID替换
             *       OPEN_ACL_UNSAFE  开放的ACL(常用)
             *       CREATOR_ALL_ACL  此ACL授予创建者身份验证ID的所有权限
             *  createMode  创建节点的4中类型
             *        PERSISTENT            创建持久节点
             *        PERSISTENT_SEQUENTIAL 创建持久顺序节点
             *        EPHEMERAL             创建临时几点
             *        EPHEMERAL_SEQUENTIAL  创建临时顺序节点
             *
             */
            String persistent = zooKeeper.create("/my_persistent", "创建持久节点".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
            String persistentSequential = zooKeeper.create("/my_persistent_sequential", "创建持久顺序节点".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT_SEQUENTIAL);
            String ephemeral = zooKeeper.create("/my_ephemeral", "创建临时节点".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
            String ephemeralSequential= zooKeeper.create("/my_ephemeral_sequential", "创建临时顺序节点".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
    
            System.out.println("持久节点 "+persistent);
            System.out.println("持久顺序节点 "+persistentSequential);
            System.out.println("临时节点 "+ephemeral);
            System.out.println("临时顺序节点 "+ephemeralSequential);
        }

    完整的test代码

    package city.albert.api;
    
    import org.apache.zookeeper.*;
    
    import java.io.IOException;
    
    /**
     * @author niunafei
     * @function
     * @email niunafei0315@163.com
     * @date 2020/7/30  3:30 PM
     */
    public class CreateZNodeBySession implements Watcher {
    
       private static   ZooKeeper zooKeeper;
    
        /**
         * 建立会话
         * 客户端创建一个连接链接zk
         *
         * @param args
         */
        public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
    
            //获取zk链接会话对象    ip+端口,超时时间   watcher回调函数
             zooKeeper = new ZooKeeper("127.0.0.1:2181", 10000, new CreateZNodeBySession());
    
            System.out.println(zooKeeper.getState());
    
            Thread.sleep(Integer.MAX_VALUE);
        }
    
        /**
         * 创建节点
         *
         * @param zooKeeper
         */
        private static void createZNode(ZooKeeper zooKeeper) throws KeeperException, InterruptedException {
            /**
             * path 创建节点路径
             * data[]  节点值的字节数组
             *  acl  节点权限4中类型
             *       ANYONE_ID_UNSAFE  标识任何人
             *       AUTH_IDS    仅仅这个id才可以设置ACL,他将被客户端验证ID替换
             *       OPEN_ACL_UNSAFE  开放的ACL(常用)
             *       CREATOR_ALL_ACL  此ACL授予创建者身份验证ID的所有权限
             *  createMode  创建节点的4中类型
             *        PERSISTENT            创建持久节点
             *        PERSISTENT_SEQUENTIAL 创建持久顺序节点
             *        EPHEMERAL             创建临时几点
             *        EPHEMERAL_SEQUENTIAL  创建临时顺序节点
             *
             */
            String persistent = zooKeeper.create("/my_persistent", "创建持久节点".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
            String persistentSequential = zooKeeper.create("/my_persistent_sequential", "创建持久顺序节点".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT_SEQUENTIAL);
            String ephemeral = zooKeeper.create("/my_ephemeral", "创建临时节点".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
            String ephemeralSequential= zooKeeper.create("/my_ephemeral_sequential", "创建临时顺序节点".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
    
            System.out.println("持久节点 "+persistent);
            System.out.println("持久顺序节点 "+persistentSequential);
            System.out.println("临时节点 "+ephemeral);
            System.out.println("临时顺序节点 "+ephemeralSequential);
        }
    
    
        /**
         * 处理来自服务器端的watcher
         *
         * @param watchedEvent
         */
        @Override
        public void process(WatchedEvent watchedEvent) {
    
            System.out.println(watchedEvent.toString());
            if (watchedEvent.getState() == Event.KeeperState.SyncConnected) {
                System.out.println("process 执行了。。。");
    
                //创建节点
                try {
                    createZNode(zooKeeper);
                } catch (KeeperException e) {
                    e.printStackTrace();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    
    
    }
    View Code

    3、获取zk的数据节点以及子节点 

    由于代码篇幅问题,下面先介绍重点代码,然后附带测试的源代码~~注意哦!

    类似命令:

       ls /    获取当前节点多有节点

       ls  /my_persist2  获取当前节点所有子节点(下面getChildren方法)

       getAllChildrenNumber  获取当前节点下子节点个数

       get  /my_persist2   获取节点数据值(下面getData方法)

    重点代码:

       public void getData() throws KeeperException, InterruptedException {
            /**
             * 获取某个节点数据api
             *  path,  获取数据的节点路径
             *  watcher,  是否开启监听,
             *   stat    节点状态   null为最新版本数据
             */
    
            byte[] data = zooKeeper.getData("/my_persistent", false, null);
            System.out.println(new String(data));
            /**
             * 获取某个节点的子节点方法
             *  path,  获取数据的节点路径
             *  watcher,  是否开启监听,
             *          当开启监听在节点变更的时候Watcher.process会返回: watchedEvent.getType()==Event.EventType.NodeChildrenChanged 类型,
             *          监听通知成功监听失效(因为通知是1次性有效,需要反复注册)
             */
            List<String> children = zooKeeper.getChildren("/", true, null);
            System.out.println(children);
    
        }

    下面为测试源码获取节点数据的

    package city.albert.api;
    
    import org.apache.zookeeper.*;
    
    import java.io.IOException;
    import java.util.List;
    
    /**
     * @author niunafei
     * @function
     * @email niunafei0315@163.com
     * @date 2020/7/30  3:30 PM
     */
    public class GetZNodeBySession implements Watcher {
    
        private static ZooKeeper zooKeeper;
    
        /**
         * 建立会话
         * 客户端创建一个连接链接zk
         *
         * @param args
         */
        public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
    
            //获取zk链接会话对象    ip+端口,超时时间   watcher回调函数
            zooKeeper = new ZooKeeper("127.0.0.1:2181", 10000, new GetZNodeBySession());
    
            System.out.println(zooKeeper.getState());
    
            Thread.sleep(Integer.MAX_VALUE);
        }
    
        /**
         * 处理来自服务器端的watcher
         *
         * @param watchedEvent
         */
        @Override
        public void process(WatchedEvent watchedEvent) {
    
            if (watchedEvent.getType() == Event.EventType.NodeChildrenChanged) {
                try {
                    getData();
                } catch (KeeperException e) {
                    e.printStackTrace();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
    
            System.out.println(watchedEvent.toString());
            if (watchedEvent.getState() == Event.KeeperState.SyncConnected) {
                System.out.println("process 执行了。。。");
    
                //获取zk节点
    
                try {
                    getData();
                } catch (KeeperException e) {
                    e.printStackTrace();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    
    
        public void getData() throws KeeperException, InterruptedException {
            /**
             * 获取某个节点数据api
             *  path,  获取数据的节点路径
             *  watcher,  是否开启监听,
             *   stat    节点状态   null为最新版本数据
             */
    
            byte[] data = zooKeeper.getData("/my_persistent", false, null);
            System.out.println(new String(data));
            /**
             * 获取某个节点的子节点方法
             *  path,  获取数据的节点路径
             *  watcher,  是否开启监听,
             *          当开启监听在节点变更的时候Watcher.process会返回: watchedEvent.getType()==Event.EventType.NodeChildrenChanged 类型,
             *          监听通知成功监听失效(因为通知是1次性有效,需要反复注册)
             */
            List<String> children = zooKeeper.getChildren("/", true, null);
            System.out.println(children);
    
        }
    }
    View Code

    4、更新zk的数据节点

    由于代码篇幅问题,下面先介绍重点代码,然后附带测试的源代码~~注意哦!

    类似操作:set  /my_persist2  678

    重点代码:

    private void updateData() throws KeeperException, InterruptedException {
    
            /**
             * 更新节点内容
             *  path, 节点路径
             *  data, 更新节点数据内容
             *  version  更新版本 -1默认最新版本
             */
            zooKeeper.setData("/my_persist2","687".getBytes(),-1);
        }

    下面为获取节点数据的测试源码

    package city.albert.api;
    
    import org.apache.zookeeper.KeeperException;
    import org.apache.zookeeper.WatchedEvent;
    import org.apache.zookeeper.Watcher;
    import org.apache.zookeeper.ZooKeeper;
    
    import java.io.IOException;
    import java.util.List;
    
    /**
     * @author niunafei
     * @function
     * @email niunafei0315@163.com
     * @date 2020/7/30  3:30 PM
     */
    public class UpdateZNodeBySession implements Watcher {
    
        private static ZooKeeper zooKeeper;
    
        /**
         * 建立会话
         * 客户端创建一个连接链接zk
         *
         * @param args
         */
        public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
    
            //获取zk链接会话对象    ip+端口,超时时间   watcher回调函数
            zooKeeper = new ZooKeeper("127.0.0.1:2181", 10000, new UpdateZNodeBySession());
    
            System.out.println(zooKeeper.getState());
    
            Thread.sleep(Integer.MAX_VALUE);
        }
    
        /**
         * 处理来自服务器端的watcher
         *
         * @param watchedEvent
         */
        @Override
        public void process(WatchedEvent watchedEvent) {
    
            System.out.println(watchedEvent.toString());
            if (watchedEvent.getState() == Event.KeeperState.SyncConnected) {
                System.out.println("process 执行了。。。");
    
                //获取zk节点
                try {
                    updateData();
                } catch (KeeperException e) {
                    e.printStackTrace();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    
        private void updateData() throws KeeperException, InterruptedException {
    
            /**
             * 更新节点内容
             *  path, 节点路径
             *  data, 更新节点数据内容
             *  version  更新版本 -1默认最新版本
             */
            zooKeeper.setData("/my_persist2","687".getBytes(),-1);
        }
    
    
    }
    View Code

    5、删除zk的数据节点

    由于代码篇幅问题,下面先介绍重点代码,然后附带测试的源代码~~注意哦!

    类似操作:delete  /my_persist2 

    private void deleteData() throws KeeperException, InterruptedException {
    
            /**
             * 删除节点内容
             *  path, 节点路径
             *  version  更新版本 -1默认最新版本
             */
            zooKeeper.delete("/my_persist2", -1);
        }

    下面为获取节点数据的测试源码

    package city.albert.api;
    
    import org.apache.zookeeper.KeeperException;
    import org.apache.zookeeper.WatchedEvent;
    import org.apache.zookeeper.Watcher;
    import org.apache.zookeeper.ZooKeeper;
    
    import java.io.IOException;
    
    /**
     * @author niunafei
     * @function
     * @email niunafei0315@163.com
     * @date 2020/7/30  3:30 PM
     */
    public class DeleteZNodeBySession implements Watcher {
    
        private static ZooKeeper zooKeeper;
    
        /**
         * 建立会话
         * 客户端创建一个连接链接zk
         *
         * @param args
         */
        public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
    
            //获取zk链接会话对象    ip+端口,超时时间   watcher回调函数
            zooKeeper = new ZooKeeper("127.0.0.1:2181", 10000, new DeleteZNodeBySession());
    
            System.out.println(zooKeeper.getState());
    
            Thread.sleep(Integer.MAX_VALUE);
        }
    
        /**
         * 处理来自服务器端的watcher
         *
         * @param watchedEvent
         */
        @Override
        public void process(WatchedEvent watchedEvent) {
    
            System.out.println(watchedEvent.toString());
            if (watchedEvent.getState() == Event.KeeperState.SyncConnected) {
                System.out.println("process 执行了。。。");
    
                //获取zk节点
                try {
                    deleteData();
                } catch (KeeperException e) {
                    e.printStackTrace();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    
        private void deleteData() throws KeeperException, InterruptedException {
    
            /**
             * 删除节点内容
             *  path, 节点路径
             *  version  更新版本 -1默认最新版本
             */
            zooKeeper.delete("/my_persist2", -1);
        }
    
    
    }
    View Code

    二、使用zkClient客户端连接

    1、引入pom文件

            <dependency>
                <groupId>com.101tec</groupId>
                <artifactId>zkclient</artifactId>
                <version>0.2</version>
            </dependency>

    2、创建zkClient对象以及操作

    操作包括:

      创建节点、顺序节点、临时节点、临时顺序节点、递归创建节点。

      获取子节点列表,以及注册监听。

      修改节点值

      判断节点是否存在

      读取节点值

      删除节点、递归删除节点

    package city.albert.api;
    
    import org.I0Itec.zkclient.IZkChildListener;
    import org.I0Itec.zkclient.ZkClient;
    import org.apache.zookeeper.CreateMode;
    
    import java.util.List;
    import java.util.concurrent.TimeUnit;
    
    /**
     * @author niunafei
     * @function
     * @email niunafei0315@163.com
     * @date 2020/8/5  5:17 PM
     */
    public class ZKSession {
        public static void main(String[] args) throws InterruptedException {
            //借助zkClient创建会话 ,ZkClient借助zk原生spi的异步建立连接进行了实现为同步
            ZkClient zkClient = new ZkClient("127.0.0.1:2181");
    
            //创建节点可以实现原生的方法递归调用创建createPersistent(path,true)方法非递归,先创建父节点在创建子节点
            //创建节点
            zkClient.create("/temp1", "11111", CreateMode.PERSISTENT);
            zkClient.create("/temp1/z1", "11111", CreateMode.PERSISTENT);
            //(递归)创建持久节点
            zkClient.createPersistent("/zkClient/zk1", true);
            //创建持久顺序节点
            zkClient.createPersistentSequential("/zkClient/zk2", "z2");
            //创建临时节点
            zkClient.createEphemeral("/zkClient/zk3", "z3");
            //创建临时顺序节点
            zkClient.createEphemeralSequential("/zkClient/zk4", "z4");
    
            //获取子节点,同时注册监听
            List<String> temp1 = zkClient.getChildren("/temp1");
            System.out.println("temp1 =" + temp1);
            List<String> zc = zkClient.getChildren("/zkClient");
            System.out.println("zkClient =" + zc);
    
            //为节点注册监听
            zkClient.subscribeChildChanges("/zkClient", new IZkChildListener() {
                @Override
                public void handleChildChange(String s, List<String> list) throws Exception {
                    System.out.println("监听节点:" + s);
                    System.out.println("监听剩余节点:" + list);
                }
            });
    
            //修改节点
            zkClient.writeData("/zkClient/zk3", "zzzz");
            //修改节点为异步事件
            TimeUnit.SECONDS.sleep(2);
    
            //判断节点是否存在
            boolean exists = zkClient.exists("/zkClient/zk3");
            System.out.println("是否存在:" + exists);
    
    
            //读取节点值
            Object o = zkClient.readData("/zkClient/zk3");
            System.out.println("读取值:" + o);
    
            //删除节点
            zkClient.delete("/temp1/z1");
            zkClient.delete("/temp1");
            //(递归) 删除节点 ,父节点为/zkClient
            zkClient.deleteRecursive("/zkClient");
        }
    }

    3、创curator对象以及操作

    curator客户端使用fluent风格编程,是netflix公司开源

     1、引入pom文件

            <dependency>
                <groupId>org.apache.curator</groupId>
                <artifactId>curator-framework</artifactId>
                <version>2.12.0</version>
            </dependency>

     2

    package city.albert.api;
    
    import org.apache.curator.RetryPolicy;
    import org.apache.curator.framework.CuratorFramework;
    import org.apache.curator.framework.CuratorFrameworkFactory;
    import org.apache.curator.retry.ExponentialBackoffRetry;
    import org.apache.zookeeper.CreateMode;
    import org.apache.zookeeper.data.Stat;
    
    /**
     * @author niunafei
     * @function
     * @email niunafei0315@163.com
     * @date 2020/8/5  6:24 PM
     */
    public class CuratorSession {
    
        public static void main(String[] args) throws Exception {
    
            //重试策略 ExponentialBackoffRetry基于ackoff重试,RetryNTimes重连n次策略,RetryForever永远重试策略
            RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
            //创建客户端对象
            CuratorFramework client = CuratorFrameworkFactory.builder()
                    .connectString("127.0.0.1:2181")
                    //链接超时时间
                    .connectionTimeoutMs(30000)
                    //创建session链接时间
                    .sessionTimeoutMs(50000)
                    //重试策略
                    .retryPolicy(retryPolicy)
                    //独立的命名空间,父节点为/base
                    .namespace("base").build();
    
            //创建链接
            client.start();
    
    
            //创建节点 ,默认创建持久节点
            //1、创建初始空节点
            client.create().forPath("/temp");
            //2、创建有内容节点
            client.create().forPath("/temp/tm", "内容".getBytes());
            client.create().forPath("/temp/tm/t1", "内容".getBytes());
            //3、递归创建父节点并且指定创建类型,EPHEMERAL是临时节点,还有持久节点,持久、临时顺序节点。
            client.create().creatingParentContainersIfNeeded().withMode(CreateMode.EPHEMERAL).forPath("/temp2/tm2", "内容2".getBytes());
    
            //获取节点值与状态信息
            byte[] bytes = client.getData().forPath("/temp/tm/t1");
            System.out.println("节点值:"+new String(bytes));
            //获取状态信息
            Stat stat = new Stat();
            client.getData().storingStatIn(stat).forPath("/temp/tm/t1");
            System.out.println("状态信息:" + stat);
    
    
            //更新节点数据
            //1、普通更新
            Stat stat1 = client.setData().forPath("/temp/tm/t1", "更新666".getBytes());
            System.out.println("更新后状态信息:"+stat1);
            System.out.println("更新后的值:"+new String(client.getData().forPath("/temp/tm/t1")));
            //2、指定版本更新,-1为最新版本
            client.setData().withVersion(-1).forPath("/temp/tm/t1","更新8888".getBytes());
            System.out.println("版本更新后的值:"+new String(client.getData().forPath("/temp/tm/t1")));
    
    
            //删除节点
            //1、删除节点
            client.delete().forPath("/temp/tm/t1");
            //2、删除并递归删除子节点
            client.delete().deletingChildrenIfNeeded().forPath("/temp2");
            //3、指定版本删除,版本不一致会抛出异常
            client.delete().withVersion(-1).forPath("/temp/tm");
            //4、保证强制删除
            client.delete().guaranteed().forPath("/temp");
    
        }
    }

    第四部分:zookeeper应用场景

     一、数据发布/订阅

      基于节点和注册监听机制实现 

    二、命名服务

      给应用,主机命名,也可以使用持久顺序节点(临时顺序节点)生成全局id,格式是job_000000001

    三、日志收集

      日志源机器和日志收集器机器的管理

    四、分布式锁

      共享锁(读锁):在固定节点下创建临时顺序节点(主机名-读/写(R/w)-0000000001),

     

      排它锁: 在固定节点下创建临时节点,创建锁(zk保证多线程创建唯一节点),使用监听机制来确定锁被释放

    五、master选举

      场景:一个广告推送服务,需要大量计算才可以获取到某个类型的推广id,使用master-slave方式

      应用技术点:选举master方式,通过创建临时节点选择(节点不可以重复创建),利用监听节点检测master状态(或者添加state节点,使用心跳机制)

      结果:master负责计算,计算结束写入某个节点,salve和master进行业务读取即可。避免了大量的重复计算

    六、分布式队列

      先进先出队列(FIFO):创建queue_fifo

      Barrier分布式屏障,类似多线程计算,计算结束进行结果汇总

    第五部分:zookeeper深入进阶


    第六部分:zookeeper源码分析

  • 相关阅读:
    U3D不同平台载入XML文件的方法——IOS MAC Android
    C++使用规范小记
    设置角色对象可见性
    编辑器菜单操作
    U3D资源动态加载异步方案探究
    Animation动画
    Unity3D失去焦点时继续渲染
    C#打开当前目录
    组件模式代码实践(C#版本)
    Unity3D批处理脚本
  • 原文地址:https://www.cnblogs.com/niunafei/p/13385656.html
Copyright © 2020-2023  润新知