zoukankan      html  css  js  c++  java
  • Zookeeper的命令行操作(三)

    Zookeeper的命令行操作

    1、 ZooKeeper服务命令

    在准备好相应的配置之后,可以直接通过zkServer.sh 这个脚本进行服务的相关操作
    
    1. 启动ZK服务:       sh bin/zkServer.sh start
    2. 查看ZK服务状态:    sh bin/zkServer.sh status
    3. 停止ZK服务:       sh bin/zkServer.sh stop
    4. 重启ZK服务:       sh bin/zkServer.sh restart
    

    2、 zk客户端命令

    启动客户端:

    ./zkCli.sh -server localhost:2181 或者
    zkCli.sh   连接到本机的zookeeper服务;
    

    ZooKeeper命令行工具类似于Linux的shell环境,不过功能肯定不及shell啦,但是使用它我们可以简单的对ZooKeeper进行访问,数据创建,数据修改等操作. 使用 zkCli.sh -server 127.0.0.1:2181 连接到 ZooKeeper 服务,连接成功后,系统会输出 ZooKeeper 的相关环境以及配置信息。

    命令行工具的一些简单操作如下:

    1. 显示根目录下、文件: ls / 使用 ls 命令来查看当前 ZooKeeper 中所包含的内容
    2. 创建文件,并设置初始内容: create /zk "test" 创建一个新的 znode节点“ zk ”以及与它关联的字符串
    3. 获取文件内容: get /zk 确认 znode 是否包含我们所创建的字符串
    4. 修改文件内容: set /zk "zkbak" 对 zk 所关联的字符串进行设置
    5. 删除文件: delete /zk 将刚才创建的 znode 删除
    6. 退出客户端: quit
    7. 帮助命令: help 
    

    我们来进入zk的客户端操作一下:

    初始化只有一个节点
    [zk: localhost:2181(CONNECTED) 0] ls /
    [zookeeper]
    创建一个节点node,值为node1
    [zk: localhost:2181(CONNECTED) 1] create /node node1
    Created /node
    [zk: localhost:2181(CONNECTED) 2] ls /
    [node, zookeeper]
    查看新建的节点,还显示了创建时间,修改时间,version,长度,children个数等
    [zk: localhost:2181(CONNECTED) 3] get /node
    node1
    cZxid = 0x2
    ctime = Mon Mar 26 14:50:55 CST 2018
    mZxid = 0x2
    mtime = Mon Mar 26 14:50:55 CST 2018
    pZxid = 0x2
    cversion = 0
    dataVersion = 0
    aclVersion = 0
    ephemeralOwner = 0x0
    dataLength = 5
    numChildren = 0
    修改新建节点的值,我们看到dataVersion,修改时间,数据长度的值变了
    [zk: localhost:2181(CONNECTED) 4] set /node reset_node_value
    cZxid = 0x2
    ctime = Mon Mar 26 14:50:55 CST 2018
    mZxid = 0x3
    mtime = Mon Mar 26 14:51:56 CST 2018
    pZxid = 0x2
    cversion = 0
    dataVersion = 1
    aclVersion = 0
    ephemeralOwner = 0x0
    dataLength = 16
    numChildren = 0
    节点的值变为修改后的值
    [zk: localhost:2181(CONNECTED) 5] get /node
    reset_node_value
    cZxid = 0x2
    ctime = Mon Mar 26 14:50:55 CST 2018
    mZxid = 0x3
    mtime = Mon Mar 26 14:51:56 CST 2018
    pZxid = 0x2
    cversion = 0
    dataVersion = 1
    aclVersion = 0
    ephemeralOwner = 0x0
    dataLength = 16
    numChildren = 0
    在node节点下创建子节点
    [zk: localhost:2181(CONNECTED) 6] create /node/sub_node sub_node_value
    Created /node/sub_node
    [zk: localhost:2181(CONNECTED) 7] ls /node
    [sub_node]
    查看父节点,numChildren的值变为1
    [zk: localhost:2181(CONNECTED) 8] get /node
    reset_node_value
    cZxid = 0x2
    ctime = Mon Mar 26 14:50:55 CST 2018
    mZxid = 0x3
    mtime = Mon Mar 26 14:51:56 CST 2018
    pZxid = 0x4
    cversion = 1
    dataVersion = 1
    aclVersion = 0
    ephemeralOwner = 0x0
    dataLength = 16
    numChildren = 1
    查看子节点
    [zk: localhost:2181(CONNECTED) 9] get /node/sub_node
    sub_node_value
    cZxid = 0x4
    ctime = Mon Mar 26 14:53:09 CST 2018
    mZxid = 0x4
    mtime = Mon Mar 26 14:53:09 CST 2018
    pZxid = 0x4
    cversion = 0
    dataVersion = 0
    aclVersion = 0
    ephemeralOwner = 0x0
    dataLength = 14
    numChildren = 0
    删除节点,发现如果父节点有子节点的话是删不了的
    [zk: localhost:2181(CONNECTED) 10] delete /node
    Node not empty: /node
    需要先删除子节点
    [zk: localhost:2181(CONNECTED) 11] delete /node/sub_node
    [zk: localhost:2181(CONNECTED) 12] delete /node
    [zk: localhost:2181(CONNECTED) 13] ls /
    [zookeeper]
    [zk: localhost:2181(CONNECTED) 14] 
    

    3、 ZooKeeper 常用四字命令

    ZooKeeper 支持某些特定的四字命令字母与其的交互。它们大多是查询命令,用来获取 ZooKeeper 服务的当前状态及相关信息。用户在客户端可以通过 telnet 或 nc 向 ZooKeeper 提交相应的命令

    1. 可以通过命令:echo stat|nc 127.0.0.1 2181 来查看哪个节点被选择作为follower或者leader
    2. 使用echo ruok|nc 127.0.0.1 2181 测试是否启动了该Server,若回复imok表示已经启动。
    3. echo dump| nc 127.0.0.1 2181 ,列出未经处理的会话和临时节点。
    4. echo kill | nc 127.0.0.1 2181 ,关掉server
    5. echo conf | nc 127.0.0.1 2181 ,输出相关服务配置的详细信息。
    6. echo cons | nc 127.0.0.1 2181 ,列出所有连接到服务器的客户端的完全的连接 / 会话的详细信息。
    7. echo envi |nc 127.0.0.1 2181 ,输出关于服务环境的详细信息(区别于 conf 命令)。
    8. echo reqs | nc 127.0.0.1 2181 ,列出未经处理的请求。
    9. echo wchs | nc 127.0.0.1 2181 ,列出服务器 watch 的详细信息。
    10. echo wchc | nc 127.0.0.1 2181 ,通过 session 列出服务器 watch 的详细信息,它的输出是一个与 watch 相关的会话的列表。
    11. echo wchp | nc 127.0.0.1 2181 ,通过路径列出服务器 watch 的详细信息。它输出一个与 session 相关的路径。 
    

    4、Zookeeper java API使用

    创建一个maven工程,加入zookeeper的jar包:

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

    测试代码如下:

    import org.apache.zookeeper.*;
    import org.apache.zookeeper.data.Stat;
    
    import java.io.IOException;
    import java.util.List;
    
    
    public class Test1 {
        private ZooKeeper zk = null;
    
        /**
         * 创建ZK连接
         * @param connectString
         * @param sessionTimeout
         */
        public void createConnection( String connectString, int sessionTimeout ) {
            this.releaseConnection();
            try {
                zk = new ZooKeeper(connectString,
                        sessionTimeout, new Watcher() {
                    // 监控所有被触发的事件
                    public void process(WatchedEvent event) {
                        // TODO Auto-generated method stub
                        System.out.println("已经触发了" + event.getType() + "事件!");
                    }
                });
            } catch ( IOException e ) {
                System.out.println( "连接创建失败,发生 IOException" );
                e.printStackTrace();
            }
        }
    
        /**
         * 关闭ZK连接
         */
        public void releaseConnection() {
            if ( zk != null ) {
                try {
                    this.zk.close();
                } catch ( InterruptedException e ) {
                    // ignore
                    e.printStackTrace();
                }
            }
        }
    
        /**
         *  创建节点
         * @param path 节点path
         * @param data 初始数据内容
         * @return
         */
        public boolean createPath( String path, String data ) {
            try {
                String node = zk.create( path, data.getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE,  CreateMode.PERSISTENT );//临时、永久...节点
                System.out.println( "节点创建成功, Path: "
                        +  node
                        + ", content: " + data );
            } catch ( KeeperException e ) {
                System.out.println( "节点创建失败,发生KeeperException" );
                e.printStackTrace();
            } catch ( InterruptedException e ) {
                System.out.println( "节点创建失败,发生 InterruptedException" );
                e.printStackTrace();
            }
            return true;
        }
    
        /**
         * 读取指定节点数据内容
         * @param path 节点path
         * @return
         */
        public String readData( String path ) {
            try {
                String res = new String( zk.getData( path, false, null ) );
                System.out.println( "获取数据成功:" + res );
                return res;
            } catch ( KeeperException e ) {
                System.out.println( "读取数据失败,发生KeeperException,path: " + path  );
                e.printStackTrace();
                return "";
            } catch ( InterruptedException e ) {
                System.out.println( "读取数据失败,发生 InterruptedException,path: " + path  );
                e.printStackTrace();
                return "";
            }
        }
    
        /**
         * 更新指定节点数据内容
         * @param path 节点path
         * @param data  数据内容
         * @return
         */
        public boolean writeData( String path, String data ) {
            try {
    
                Stat stat = zk.setData( path, data.getBytes(), -1 );//-1表示匹配所有版本
                System.out.println( "更新数据成功,path:" + path + ", stat: " + stat);
            } catch ( KeeperException e ) {
                System.out.println( "更新数据失败,发生KeeperException,path: " + path  );
                e.printStackTrace();
            } catch ( InterruptedException e ) {
                System.out.println( "更新数据失败,发生 InterruptedException,path: " + path  );
                e.printStackTrace();
            }
            return false;
        }
    
        /**
         * 删除指定节点
         * @param path 节点path
         */
        public void deleteNode( String path ) {
            try {
                zk.delete( path, -1 );
                System.out.println( "删除节点成功,path:" + path );
            } catch ( KeeperException e ) {
                System.out.println( "删除节点失败,发生KeeperException,path: " + path  );
                e.printStackTrace();
            } catch ( InterruptedException e ) {
                System.out.println( "删除节点失败,发生 InterruptedException,path: " + path  );
                e.printStackTrace();
            }
        }
    
        public List<String> getChildrens(String path ) {
            try {
                return zk.getChildren(path, true);
            } catch ( KeeperException e ) {
                System.out.println( "删除节点失败,发生KeeperException,path: " + path  );
                e.printStackTrace();
                return null;
            } catch ( InterruptedException e ) {
                System.out.println( "删除节点失败,发生 InterruptedException,path: " + path  );
                e.printStackTrace();
                return null;
            }
        }
    
        /**
         * @param args
         * @throws Exception
         */
        public static void main(String[] args) throws Exception {
            Test1 test = new Test1();
            test.createConnection("192.168.27.130:2181", 3000);
    
            test.createPath("/node", "node2");
            test.readData("/node");
    
            test.createPath("/node/node1", "node1");
            test.readData("/node/node1");
    
            List<String> childrens = test.getChildrens("/node");
            for (String str :childrens) {
                System.out.println(str);
            }
    
            test.releaseConnection();
        }
    }
    

    执行完main方法之后我们去zk的控制台去看一下是否创建创建成功:

    [zk: localhost:2181(CONNECTED) 14] ls /
    [node, zookeeper]
    [zk: localhost:2181(CONNECTED) 15] ls /node
    [node1]
    

    可以看到已经成功创建了。

    4.1 zk创建节点

    zk create API 方法参数说明:

    参数名 描述
    path 常妥创建的数据节点的节点路径
    data[] 一个字节数组,是节点创建后的初始内容
    acl 节点ACL策略
    createMode 节点类型:
    持久:PERSITENT;
    持久顺序:PERSISTENT_SEQUENTIAL;
    临时:EPHEMERAL;
    临时顺序:EPHEMERAL_SEUQUENTIAL
    cb 注册一个异步回调函数。开发人员需要实现StringCallback 接口;当服务将节点创建完毕后zk 客户端就会自动调用这个方法,这样就可以处理相关的业务逻辑了
    ctx 用于传递一个对象, 可以在回调方法执行的时候使用,通常是放一个上下文(Context)信息

    使用同步API 创建一个节点:

    import com.alibaba.fastjson.JSONObject;
    import org.apache.zookeeper.CreateMode;
    import org.apache.zookeeper.ZooDefs;
    import org.apache.zookeeper.ZooKeeper;
    
    import java.io.IOException;
    import java.util.List;
    
    public class Demo1 {
        public static void main(String[] args) {
            try {
                ZooKeeper zooKeeper = new ZooKeeper("192.168.131.128:2181",5000,new DemoWatcher());
                String path1 = zooKeeper.create("/test","haha".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE,CreateMode.EPHEMERAL);
                System.out.println("zkNode create success: "+path1);
                String path2 = zooKeeper.create("/test/test1","t2".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE,CreateMode.EPHEMERAL);
                System.out.println(path2);
                List<String> childrenList = zooKeeper.getChildren("/test",new DemoWatcher());
                System.out.println(JSONObject.toJSON(childrenList));
    
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    

    DemoWatch:

    import org.apache.zookeeper.WatchedEvent;
    import org.apache.zookeeper.Watcher;
    
    public class DemoWatcher implements Watcher {
    
        @Override
        public void process(WatchedEvent watchedEvent) {
            System.out.println("watch path: "+watchedEvent.getPath());
            System.out.println("watch event is: "+watchedEvent);
    
        }
    }
    

    使用异步方法创建节点:

    import com.alibaba.fastjson.JSONObject;
    import org.apache.zookeeper.CreateMode;
    import org.apache.zookeeper.ZooDefs;
    import org.apache.zookeeper.ZooKeeper;
    
    import java.io.IOException;
    import java.util.List;
    
    public class Demo1 {
        public static void main(String[] args) {
            try {        
                ZooKeeper zooKeeper = new ZooKeeper("192.168.131.128:2181",5000,new DemoWatcher());
                zooKeeper.create("/test","haha".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL,new ZkCallBack(),"callback");
                zooKeeper.create("/test/test1","t2".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE,CreateMode.EPHEMERAL,new ZkCallBack(),"callback");
                List<String> childrenList = zooKeeper.getChildren("/test",new DemoWatcher());
                System.out.println(JSONObject.toJSON(childrenList));
    
    
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    
    ZkCallBack:
    
    
    import org.apache.zookeeper.AsyncCallback;
    
    public class ZkCallBack implements AsyncCallback.StringCallback {
        @Override
        public void processResult(int i, String s, Object o, String s1) {
            System.out.println("create path result : "+ i + " "+ s+" "+s1);
        }
    }
    
    4.2 zk权限控制

    zk权限控制模式分别有:

    1. world:默认方式,相当于全世界都能访问
    2. auth:代表已经认证通过的用户(cli中可以通过addauth digest user:pwd 来添加当前上下文中的授权用户)
    3. digest:即用户名:密码这种方式认证,这也是业务系统中最常用
    4. ip:使用Ip地址认证

    下面举个例子:

    public class Demo1 {
        public static void main(String[] args) {
            try {
                ZooKeeper zooKeeper = new ZooKeeper("192.168.131.128:2181",5000,new DemoWatcher());
                zooKeeper.addAuthInfo("digest","sa:123".getBytes());
                String path1 = zooKeeper.create("/test","haha".getBytes(), ZooDefs.Ids.CREATOR_ALL_ACL, CreateMode.EPHEMERAL);
                System.out.println("zkNode create success: "+path1);
    
                ZooKeeper zooKeeper2 = new ZooKeeper("192.168.131.128:2181",5000,new DemoWatcher());
                zooKeeper2.getData("/test",new DemoWatcher(),null);
    
                ZooKeeper zooKeeper3 = new ZooKeeper("192.168.131.128:2181",5000,new DemoWatcher());
                zooKeeper3.addAuthInfo("digest","sa:321".getBytes());
                zooKeeper3.getData("/test",new DemoWatcher(),null);
    
                ZooKeeper zooKeeper4 = new ZooKeeper("192.168.131.128:2181",5000,new DemoWatcher());
                zooKeeper4.addAuthInfo("digest","sa:123".getBytes());
                zooKeeper4.getData("/test",new DemoWatcher(),null);
    
    
    
    
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    

    运行到zk2实例的时候就会报错:

    org.apache.zookeeper.KeeperException$NoAuthException: KeeperErrorCode = NoAuth for /test
    

    同样zk3也会出错,zk4可以通过。

  • 相关阅读:
    【Nginx】Nginx性能优化及配置文件
    【算法】常见算法分类和思想
    【PHP】php位运算及其高级应用
    【数据结构】数据结构-图的基本概念
    【Redis】Redis缓存穿透解决方案之布隆过滤器
    【Linux】Linux系统5种IO模型
    【linux】/dev/null作用和/dev/random
    【Linux】Linux查找功能
    【算法】算法复杂度
    Docker Hub公共镜像仓库的使用
  • 原文地址:https://www.cnblogs.com/rickiyang/p/11074198.html
Copyright © 2011-2022 走看看