美文网首页
zookeeper入门

zookeeper入门

作者: 紫色红色黑色 | 来源:发表于2019-11-27 12:06 被阅读0次

    描述

    zookeeper是分布式协调组件,使用java开发,安装时需要JVM环境。
    1.使用客户端-服务器模型。客户端会定时ping一台服务器。每个服务器可以处理大量客户端请求。如果客户端没有收到服务器pong,则会连接另一台服务器。客户端会话会转移到这台服务器上。
    2.读操作时,客户端请求服务端数据。写数据时,客户端请求服务器写数据,服务器请求leader写数据,leader通知所有服务器写数据,如果多数服务器回应写操作,则认为写操作完成。

    定义

    zookeeper使用类似unix文件系统存储数据,是树形结构。每个节点称为znode。znode中维护stat结构。stat由版本号、操作控制列表(acl)、时间戳、数据长度组成。

    • 版本号:每次znode数据变更会生成一个版本号
    • acl:表示znode数据操作权限
    • 时间戳:
    • 数据长度:存储znode数据长度,最大可以存储1MB

    znode节点类型

    • Persistent znode:持久性。默认情况,非特殊指明的都是持久性
    • Ephemeral znode:临时性。Session结束后,该类型的znode消失
    • Sequence znode:顺序性。可以和持久性或者临时性一起使用的znode

    Session
    客户端连接上服务器后,将建立会话。服务器会分配SessionID给客户端。客户端发送心跳给服务器保持会话正常。服务器在指定时间内没有收到客户端心跳,则判断客户端死机。Session中的请求按照FIFO策略执行。

    Watch
    客户端接受zookeeper集群中更改的通知。一个watch事件一次性的触发器,当设置watch的数据发生变更时,则服务器将这个通知发送给设置watch的客户端。


    watch事件

    安装

    单机安装

    1.下载zookeeper解压。在conf目录中新建zoo.cfg。修改配置dataDir项
    2.启动服务器

    # 命令
    ./zkServer.sh start
    
    #显示
    /usr/bin/java
    ZooKeeper JMX enabled by default
    Using config: /Users/lucy/Documents/zookeeper/apache-zookeeper-3.5.6-bin/bin/../conf/zoo.cfg
    Starting zookeeper ... STARTED
    

    3.启动cli测试

    # 命令
    ./zkClient.sh
    

    单机伪集群搭建

    1.解压一个zookeeper安装包,conf下创建zoo.cfg。配置文件中修改dataDir和clientPort,并在dataDir下新建myid文件。myid文件内容是1。

    #修改配置
    dataDir=/Users/lucy/Documents/zookeeper/apache-zookeeper-3.5.6-bin-1/tmp/zookeeper
    clientPort=2181
    
    #增加配置
    server.1=127.0.0.1:2888:3888
    server.2=127.0.0.1:2889:3889
    server.3=127.0.0.1:2890:3890
    

    2.复制上述配置的zookeeper两份,每一个需要修改zoo.cfg中dataDir、clientPort和myid中的值

    3.解释

    server.n=ip:port1:port2
    
    项目 描述
    server.n 服务器节点ID,n和myid中的数字保持一致
    ip:port1:port2 服务器ip:flower和leader通信端口:leader选举端口

    命令行

    连接到服务器,如果没有参数就连接本机的服务器。可以查看命令行

    ./zkCli.sh -server 127.0.0.1:2181
    
    命令项 格式 实例
    查看路径下znode ls path ls /
    创建znode create path data acl create /zk_test my_data
    查看znode值 get path get /zk_test
    设置znode值 set path data set /zk_test my_data_1
    删除znode delete path delete /zk_test
    递归删除节点及其子节点 deleteall path deleteall /zk_test

    创建节点

    -s创建顺序性znode。path为/test表示znode名称前缀为test,path为/表示znode名称没有前缀
    -e创建临时性znode

    # 创建前缀为test的顺序znode
    [zk: localhost:2181(CONNECTED) 6] create -s /test lucy
    Created /test0000000010
    
    # 创建没有前缀的顺序znode
    [zk: localhost:2181(CONNECTED) 7] create -s / lucy
    Created /0000000011
    
    # 创建临时性znode
    [zk: localhost:2181(CONNECTED) 21] create -e /test lucy
    Created /test
    

    java客户端

    1.maven中引入zookeeper官方客户端依赖,也可以使用curator

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

    2.代码

    public static void main(String[] args) throws Exception {
    
        String connectString = "127.0.0.1:2181,127.0.0.1:2182,127.0.0.1:2183";
    
        CountDownLatch latch = new CountDownLatch(1);
        ZooKeeper zooKeeper = new ZooKeeper(connectString, 5000, event -> {
    
            System.out.println("watcher action type=" + event.getType() + " state=" + event.getState());
    
            /**
                * watcher有枚举event、watchertype
                * event(事件类型)
                *      KeeperState(连接时类型):None、Disconnected、SyncConnected...
                *      EventType(crud类型):NodeCreated、NodeDataChanged...
                * WatcherType(父子类型):Children、Data
                */
            if (event.getState() == Watcher.Event.KeeperState.SyncConnected) {
                switch (event.getType()) {
                    case None:
                        latch.countDown();
                        break;
                    case NodeCreated:
                        System.out.println("node create " + event.getPath());
                        break;
                    default:
                        break;
                }
            }
        });
    
        latch.await();
    
        // 测试数据
        String path = "/lucy";
        String data1 = "Hello,World";
        String data2 = "Hello,Lucy";
    
        // true表示监听该znode,watcher是zookeeper实例化中指定的watcher
        Stat exists1 = zooKeeper.exists(path, true);
        if (exists1 != null) {
            // version是cas用的,设置为-1,不检查版本号。返回znode的Stat
            Stat setStat = zooKeeper.setData(path, data2.getBytes(), -1);
        } else {
            // acl指定znode的权限,createMode指定znode类型。返回znode的data
            String result = zooKeeper.create(path, data1.getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
        }
    
        //Stat 存储查询条件
        byte[] data = zooKeeper.getData(path, false, null);
        if (data != null) {
            System.out.println("data=" + new String(data));
        }
    
        zooKeeper.delete(path, -1);
    
        zooKeeper.close();
    }
    

    引用

    https://www.w3cschool.cn/zookeeper/zookeeper_fundamentals.html
    https://www.ibm.com/developerworks/cn/data/library/bd-zookeeper/index.html#artrelatedtopics
    https://segmentfault.com/a/1190000016349824
    https://www.ibm.com/developerworks/cn/opensource/os-cn-zookeeper/index.html
    https://zookeeper.apache.org/
    https://www.cnblogs.com/dennisit/p/4340688.html
    http://www.glmapper.com/2019/04/13/zookeeper-client-curator/
    https://www.ibm.com/developerworks/cn/opensource/os-cn-apache-zookeeper-watcher/index.html
    https://github.com/apache/zookeeper/blob/master/zookeeper-docs/src/main/resources/markdown/zookeeperCLI.md

    相关文章

      网友评论

          本文标题:zookeeper入门

          本文链接:https://www.haomeiwen.com/subject/dbuswctx.html