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可以通过。

  • 相关阅读:
    hdu 1199 Color the Ball 离散线段树
    poj 2623 Sequence Median 堆的灵活运用
    hdu 2251 Dungeon Master bfs
    HDU 1166 敌兵布阵 线段树
    UVALive 4426 Blast the Enemy! 计算几何求重心
    UVALive 4425 Another Brick in the Wall 暴力
    UVALive 4423 String LD 暴力
    UVALive 4872 Underground Cables 最小生成树
    UVALive 4870 Roller Coaster 01背包
    UVALive 4869 Profits DP
  • 原文地址:https://www.cnblogs.com/rickiyang/p/11074198.html
Copyright © 2011-2022 走看看