zoukankan      html  css  js  c++  java
  • Linux系统下zookeeper客户端命令使用

    1. 启动客户端

    [admin@yrjk bin]$ ./zkCli.sh 
    [zk: localhost:2181(CONNECTED) 0] 

    2. 显示所有操作命令

    [zk: localhost:2181(CONNECTED) 0] help
    ZooKeeper -server host:port cmd args
        stat path [watch]
        set path data [version]
        ls path [watch]
        delquota [-n|-b] path
        ls2 path [watch]
        setAcl path acl
        setquota -n|-b val path
        history 
        redo cmdno
        printwatches on|off
        delete path [version]
        sync path
        listquota path
        rmr path
        get path [watch]
        create [-s] [-e] path data acl
        addauth scheme auth
        quit 
        getAcl path
        close 
        connect host:port
    [zk: localhost:2181(CONNECTED) 1] 

    3. 查看节点

    [zk: localhost:2181(CONNECTED) 1] ls /      # ls命令用于查看节点,类似于Linux中的查看目录
    [zookeeper]
    [zk: localhost:2181(CONNECTED) 2] ls2 /     # ls2命令用于查看节点以及该节点状态的详细信息
    [zookeeper]
    cZxid = 0x0
    ctime = Thu Jan 01 08:00:00 CST 1970
    mZxid = 0x0
    mtime = Thu Jan 01 08:00:00 CST 1970
    pZxid = 0x0
    cversion = -1
    dataVersion = 0
    aclVersion = 0
    ephemeralOwner = 0x0
    dataLength = 0
    numChildren = 1
    [zk: localhost:2181(CONNECTED) 3] 

    节点状态的属性描述如下:

    [zk: localhost:2181(CONNECTED) 3] create /name Richard
    Created /name
    [zk: localhost:2181(CONNECTED) 4] stat /name     # stat命令用于查看节点状态的详细信息
    cZxid = 0x6
    ctime = Sun Dec 15 13:25:02 CST 2019
    mZxid = 0x6
    mtime = Sun Dec 15 13:25:02 CST 2019
    pZxid = 0x6
    cversion = 0
    dataVersion = 0
    aclVersion = 0
    ephemeralOwner = 0x0
    dataLength = 7
    numChildren = 0
    [zk: localhost:2181(CONNECTED) 5] get /name      # get命令用于查看节点的数据以及节点状态的详细信息
    Richard
    cZxid = 0x6
    ctime = Sun Dec 15 13:25:02 CST 2019
    mZxid = 0x6
    mtime = Sun Dec 15 13:25:02 CST 2019
    pZxid = 0x6
    cversion = 0
    dataVersion = 0
    aclVersion = 0
    ephemeralOwner = 0x0
    dataLength = 7
    numChildren = 0
    [zk: localhost:2181(CONNECTED) 6]

    4. 节点创建

    znode一共有4种类型:持久的(persistent)、临时的(ephemeral)、持久有序的(persistent_sequential)和临时有序的(ephemeral_sequential)。

    在节点创建之前,需要了解一下zk中session的特性:

    • 客户端与服务端之间的连接存在会话
    • 每个会话都可以设置一个超时时间
    • 心跳结束,session则过期
    • session过期,则临时节点znode会被抛弃
    • 心跳机制:客户端向服务端的ping包请求
    [zk: localhost:2181(CONNECTED) 2] create /name Richard
    Created /name
    [zk: localhost:2181(CONNECTED) 3] ls /
    [name, zookeeper]
    [zk: localhost:2181(CONNECTED) 4] get /name
    Richard
    cZxid = 0xe
    ctime = Sun Dec 15 13:53:22 CST 2019
    mZxid = 0xe
    mtime = Sun Dec 15 13:53:22 CST 2019
    pZxid = 0xe
    cversion = 0
    dataVersion = 0
    aclVersion = 0
    ephemeralOwner = 0x0
    dataLength = 7
    numChildren = 0
    [zk: localhost:2181(CONNECTED) 5] 

    这种创建方式创建出来的节点是持久化的,也就是持久节点(PERSISTENT)。所谓持久节点,是指在节点创建后,就一直存在,直到有删除操作来主动清除这个节点——不会因为创建该节点的客户端会话失效而消失。除了持久节点之外,我们还可以创建临时节点(EPHEMERAL),那么我们来看看如何创建临时节点:

    [zk: localhost:2181(CONNECTED) 5] create -e /name/tmp Rachel 
    Created /name/tmp      # -e 指定创建临时节点
    [zk: localhost:2181(CONNECTED) 6] get /name
    Richard
    cZxid = 0xe
    ctime = Sun Dec 15 13:53:22 CST 2019
    mZxid = 0xe
    mtime = Sun Dec 15 13:53:22 CST 2019
    pZxid = 0xf
    cversion = 1   #由于在/name下创建了一个子节点,所以 cversion 的值就会进行累加
    dataVersion = 0
    aclVersion = 0
    ephemeralOwner = 0x0    #表示持久节点
    dataLength = 7
    numChildren = 1
    [zk: localhost:2181(CONNECTED) 7] get /name/tmp
    Rachel
    cZxid = 0xf
    ctime = Sun Dec 15 13:56:09 CST 2019
    mZxid = 0xf
    mtime = Sun Dec 15 13:56:09 CST 2019
    pZxid = 0xf
    cversion = 0
    dataVersion = 0
    aclVersion = 0
    ephemeralOwner = 0x100000be9f80004   #表示临时节点
    dataLength = 6
    numChildren = 0
    [zk: localhost:2181(CONNECTED) 8] 

    和持久节点不同的是,临时节点的生命周期和客户端会话绑定。也就是说,如果客户端会话失效,那么这个节点就会自动被清除掉。注意,这里提到的是会话失效,而非连接断开,当然连接断开也会导致会话失效,但是并不是主要原因。另外,在临时节点下面不能创建子节点。我们上面提到了,心跳结束,session就会过期,而session过期,则临时节点znode就会被抛弃。那么我们来断开与服务端的连接,看看临时节点是否会被清除:

    [zk: localhost:2181(CONNECTED) 8] ls /name
    [tmp]
    [zk: localhost:2181(CONNECTED) 9] quit   
    Quitting...
    2019-12-15 14:00:44,326 [myid:] - INFO  [main:ZooKeeper@687] - Session: 0x100000be9f80004 closed
    2019-12-15 14:00:44,328 [myid:] - INFO  [main-EventThread:ClientCnxn$EventThread@520] - EventThread shut down for session: 0x100000be9f80004
    [admin@yrjk bin]$ ./zkCli.sh
    [zk: localhost:2181(CONNECTED) 0] ls /name    #重连之后,临时节点被清除
    []
    [zk: localhost:2181(CONNECTED) 1] 

    以上我们演示了持久节点和临时节点的创建,下面我们来看一下持久顺序节点(PERSISTENT_SEQUENTIAL)的创建:

    [zk: localhost:2181(CONNECTED) 3] create -s /name/seq num   #-s指定创建持久顺序节点
    Created /name/seq0000000001         # 会自动为给定节点名加上一个数字后缀
    [zk: localhost:2181(CONNECTED) 4] ls /name 
    [seq0000000001]
    [zk: localhost:2181(CONNECTED) 5] create -s /name/seq num
    Created /name/seq0000000002         # 再次创建节点数字就会递增
    [zk: localhost:2181(CONNECTED) 6] ls /name               
    [seq0000000001, seq0000000002]
    [zk: localhost:2181(CONNECTED) 7] create -s /name/otherseq num
    Created /name/otherseq0000000003    # 创建前缀不同的节点,数字也会递增
    [zk: localhost:2181(CONNECTED) 8] ls /name                    
    [otherseq0000000003, seq0000000001, seq0000000002]
    [zk: localhost:2181(CONNECTED) 9] 

    这类节点的基本特性和持久节点类型是一致的。额外的特性是,在ZK中,每个父节点会为他的第一级子节点维护一份时序,会记录每个子节点创建的先后顺序。基于这个特性,在创建子节点的时候,可以设置这个属性,那么在创建节点过程中,ZK会自动为给定节点名加上一个数字后缀,作为新的节点名。这个数字后缀的范围是整型的最大值。

    当 -s 与 -e 选项同时使用就是创建临时顺序节点(EPHEMERAL_SEQUENTIAL) ,此节点是属于临时节点,不过带有顺序,和临时节点一样,当session过期节点就会消失,而客户端会话连接结束也会导致session过期,所以同样的该节点也会消失,这种类型的节点一般用于实现分布式锁。以下演示一下临时顺序节点的创建方式:

    [zk: localhost:2181(CONNECTED) 9] create /address Beijing   #创建一个持久节点
    Created /address
    [zk: localhost:2181(CONNECTED) 10] create -s -e /address/road Changan   #在持久节点下,创建临时顺序节点
    Created /address/road0000000000
    [zk: localhost:2181(CONNECTED) 11] create -s -e /address/road Changan
    Created /address/road0000000001
    [zk: localhost:2181(CONNECTED) 12] create -s -e /address/street Changan
    Created /address/street0000000002
    [zk: localhost:2181(CONNECTED) 13] ls /address
    [road0000000000, road0000000001, street0000000002]
    [zk: localhost:2181(CONNECTED) 14] quit
    Quitting...
    2019-12-15 14:15:09,721 [myid:] - INFO  [main:ZooKeeper@687] - Session: 0x100000be9f80005 closed
    2019-12-15 14:15:09,723 [myid:] - INFO  [main-EventThread:ClientCnxn$EventThread@520] - EventThread shut down for session: 0x100000be9f80005
    [admin@yrjk bin]$ ./zkCli.sh
    [zk: localhost:2181(CONNECTED) 0] ls /address 
    []

    5. 节点修改

    使用set命令对某个节点进行修改:

    [zk: localhost:2181(CONNECTED) 6] get /name
    Richard
    cZxid = 0xe
    ctime = Sun Dec 15 13:53:22 CST 2019
    mZxid = 0xe
    mtime = Sun Dec 15 13:53:22 CST 2019
    pZxid = 0x14
    cversion = 5
    dataVersion = 0
    aclVersion = 0
    ephemeralOwner = 0x0
    dataLength = 7
    numChildren = 3
    [zk: localhost:2181(CONNECTED) 7] set /name David   #修改/name节点的数据
    cZxid = 0xe
    ctime = Sun Dec 15 13:53:22 CST 2019
    mZxid = 0x1b
    mtime = Sun Dec 15 14:19:21 CST 2019
    pZxid = 0x14
    cversion = 5
    dataVersion = 1     # 此时数据版本就会递增为1
    aclVersion = 0
    ephemeralOwner = 0x0
    dataLength = 5
    numChildren = 3
    [zk: localhost:2181(CONNECTED) 8] get /name      
    David
    cZxid = 0xe
    ctime = Sun Dec 15 13:53:22 CST 2019
    mZxid = 0x1b
    mtime = Sun Dec 15 14:19:21 CST 2019
    pZxid = 0x14
    cversion = 5
    dataVersion = 1     # 数据版本递增为1
    aclVersion = 0
    ephemeralOwner = 0x0
    dataLength = 5
    numChildren = 3
    [zk: localhost:2181(CONNECTED) 9] 

    我们可以利用数据版本 dataVersion 来达到一个乐观锁的效果,所以每次我们修改节点数据的时候,应该加上这个 dataVersion 的值去进行修改,以免在并发的时候导致数据不一致:

    [zk: localhost:2181(CONNECTED) 9] set /name Sam 1   #指定版本去修改
    cZxid = 0xe
    ctime = Sun Dec 15 13:53:22 CST 2019
    mZxid = 0x1c
    mtime = Sun Dec 15 14:22:33 CST 2019
    pZxid = 0x14
    cversion = 5
    dataVersion = 2
    aclVersion = 0
    ephemeralOwner = 0x0
    dataLength = 3
    numChildren = 3
    [zk: localhost:2181(CONNECTED) 10] set /name Sam1 1   # 如果再次使用版本1去修改数据,就会报错
    version No is not valid : /name
    [zk: localhost:2181(CONNECTED) 11] 

    6. 节点删除

    使用delete命令可以对某个节点进行删除:

    [zk: localhost:2181(CONNECTED) 12] ls /name
    [otherseq0000000003, seq0000000001, seq0000000002]
    [zk: localhost:2181(CONNECTED) 13] delete /name/seq0000000001    #删除节点
    [zk: localhost:2181(CONNECTED) 14] ls /name                  
    [otherseq0000000003, seq0000000002]
    [zk: localhost:2181(CONNECTED) 15] delete /name/seq0000000002 0    #指定版本号删除节点
    [zk: localhost:2181(CONNECTED) 16] ls /name                  
    [otherseq0000000003]

    使用rmr命令可以对节点进行递归删除:

    [zk: localhost:2181(CONNECTED) 16] ls /     
    [name, address, zookeeper]
    [zk: localhost:2181(CONNECTED) 17] rmr /name  #递归删除节点
    [zk: localhost:2181(CONNECTED) 18] ls /     
    [address, zookeeper]
    [zk: localhost:2181(CONNECTED) 19] 

    7. watcher机制

    watcher是zk中比较重要的特性,定义如下:

    • 针对每个节点的操作,都会有一个监督者 -> watcher
    • 当监控的某个对象(znode)发生了变化,则触发watcher事件
    • 简单来说,watcher类似于sql中的触发器
    • zk中的watcher是一次性的,触发后立即销毁
    • 父节点,子节点 的增删改都能够触发其watcher
    • 针对不同类型的操作,触发的watcher事件也不同:
      • (子)节点创建事件
      • (子)节点删除事件
      • (子)节点数据变化事件

    7.1 父节点watcher事件

    watcher命令行学习:

    • 通过get path [watcher] 可以设置watcher,其他的诸如stat、ls、ls2命令也可以设置watcher
    • 父节点 增 删 改 操作触发watcher
    • 子节点 增 删 改 操作触发watcher

    watcher事件类型-父节点:

    • 创建父节点触发 NodeCreated 事件
    • 修改父节点数据触发 NodeDataChanged 事件
    • 删除父节点触发 NodeDeleted 事件

    创建父节点触发 NodeCreated 事件,示例:

    [zk: localhost:2181(CONNECTED) 19] stat /testWatch watch  # 在节点创建之前,我们可以通过 stat 命令去设置watcher
    Node does not exist: /testWatch
    [zk: localhost:2181(CONNECTED) 20] create /testWatch test-data  # 创建父节点
    
    WATCHER::
    
    WatchedEvent state:SyncConnected type:NodeCreated path:/testWatch  # 触发 NodeCreated 事件
    Created /testWatch
    [zk: localhost:2181(CONNECTED) 21]

    修改父节点数据触发 NodeDataChanged 事件,示例:

    [zk: localhost:2181(CONNECTED) 21] get /testWatch watch  # 因为zk事件是一次性的,所以我们还需要通过 get 命令设置 watcher
    test-data
    cZxid = 0x19
    ctime = Sun Apr 22 23:37:08 CST 2018
    mZxid = 0x19
    mtime = Sun Apr 22 23:37:08 CST 2018
    pZxid = 0x19
    cversion = 0
    dataVersion = 0
    aclVersion = 0
    ephemeralOwner = 0x0
    dataLength = 9
    numChildren = 0
    [zk: localhost:2181(CONNECTED) 22] set /testWatch new-data  # 修改父节点数据
    
    WATCHER::
    
    WatchedEvent state:SyncConnected type:NodeDataChanged path:/testWatch  # 触发 NodeDataChanged 事件
    cZxid = 0x19
    ctime = Sun Apr 22 23:37:08 CST 2018
    mZxid = 0x1a
    mtime = Sun Apr 22 23:40:32 CST 2018
    pZxid = 0x19
    cversion = 0
    dataVersion = 1
    aclVersion = 0
    ephemeralOwner = 0x0
    dataLength = 8
    numChildren = 0
    [zk: localhost:2181(CONNECTED) 23] 

    删除父节点触发 NodeDeleted 事件,示例:

    [zk: localhost:2181(CONNECTED) 23] ls /testWatch watch  # 通过 ls 命令来设置 watcher
    []
    [zk: localhost:2181(CONNECTED) 24] delete /testWatch  # 删除父节点
    
    WATCHER::
    
    WatchedEvent state:SyncConnected type:NodeDeleted path:/testWatch  # 触发 NodeDeleted 事件
    [zk: localhost:2181(CONNECTED) 25]

    7.2 子节点watcher事件

    watcher事件类型-子节点:

    • 使用 ls 命令为父节点设置watcher,创建子节点时就会触发 NodeChildrenChanged 事件
    • 使用 ls 命令为父节点设置watcher,删除子节点时也会触发 NodeChildrenChanged 事件
    • 使用 ls 命令为父节点设置watcher,修改子节点数据时不会触发任何事件
    • 使用 get 命令为子节点设置watcher,修改子节点数据时会触发 NodeDataChanged 事件

    使用 ls 命令为父节点设置watcher,创建子节点时就会触发 NodeChildrenChanged 事件,示例:

    [zk: localhost:2181(CONNECTED) 29] create /testWatch test-data  # 创建父节点
    Created /testWatch
    [zk: localhost:2181(CONNECTED) 30] ls /testWatch watch  # 使用 ls 命令为父节点设置watcher
    []
    [zk: localhost:2181(CONNECTED) 31] create /testWatch/testChildren children-data  # 创建子节点
    
    WATCHER::
    
    WatchedEvent state:SyncConnected type:NodeChildrenChanged path:/testWatch  # 触发 NodeChildrenChanged 事件
    Created /testWatch/testChildren
    [zk: localhost:2181(CONNECTED) 32] 

    使用 ls 命令为父节点设置watcher,删除子节点时也会触发 NodeChildrenChanged 事件,示例:

    [zk: localhost:2181(CONNECTED) 32] ls /testWatch watch   # 使用 ls 命令为父节点设置watcher
    [testChildren]
    [zk: localhost:2181(CONNECTED) 33] delete /testWatch/testChildren   # 删除子节点          
    
    WATCHER::
    
    WatchedEvent state:SyncConnected type:NodeChildrenChanged path:/testWatch   # 触发 NodeChildrenChanged 事件
    [zk: localhost:2181(CONNECTED) 34] 

    简单说明一下为什么创建和删除子节点都是触发 NodeChildrenChanged 事件,这是因为子节点都是挂在父节点之下,而我们是给父节点设置的 watcher,不是给子节点设置 watcher ,不管子节点是删除还是创建,都是一个改变的过程,所以都是触发同一个事件。

    使用 ls 命令为父节点设置watcher,修改子节点数据时不会触发任何事件,示例:

    [zk: localhost:2181(CONNECTED) 35] create /testWatch/testChildren children-data  # 创建子节点
    [zk: localhost:2181(CONNECTED) 36] ls /testWatch watch   # 使用 ls 命令为父节点设置watcher        
    [testChildren]
    [zk: localhost:2181(CONNECTED) 37] set /testWatch/testChildren new-children-data  # 修改子节点数据时不会触发任何事件
    cZxid = 0x1f
    ctime = Sun Apr 22 23:58:44 CST 2018
    mZxid = 0x20
    mtime = Sun Apr 22 23:59:24 CST 2018
    pZxid = 0x1f
    cversion = 0
    dataVersion = 1
    aclVersion = 0
    ephemeralOwner = 0x0
    dataLength = 17
    numChildren = 0
    [zk: localhost:2181(CONNECTED) 38] 

    不会触发事件是因为这个watcher是设置在父节点上的,所以修改子节点数据时不会触发父节点所设置的watcher事件。

    使用 get 命令为子节点设置watcher,修改子节点数据时会触发 NodeDataChanged 事件,示例:

    [zk: localhost:2181(CONNECTED) 40] get /testWatch/testChildren watch  # 使用 get 命令为子节点设置watcher
    new-children-data
    cZxid = 0x1f
    ctime = Sun Apr 22 23:58:44 CST 2018
    mZxid = 0x21
    mtime = Mon Apr 23 00:01:41 CST 2018
    pZxid = 0x1f
    cversion = 0
    dataVersion = 2
    aclVersion = 0
    ephemeralOwner = 0x0
    dataLength = 17
    numChildren = 0
    [zk: localhost:2181(CONNECTED) 41] set /testWatch/testChildren new-children-data2  # 修改子节点数据
    
    WATCHER::
    
    WatchedEvent state:SyncConnected type:NodeDataChanged path:/testWatch/testChildren   # 触发 NodeDataChanged 事件
    cZxid = 0x1f
    ctime = Sun Apr 22 23:58:44 CST 2018
    mZxid = 0x22
    mtime = Mon Apr 23 00:02:11 CST 2018
    pZxid = 0x1f
    cversion = 0
    dataVersion = 3
    aclVersion = 0
    ephemeralOwner = 0x0
    dataLength = 18
    numChildren = 0
    [zk: localhost:2181(CONNECTED) 42] 

    参考:ZooKeeper:分布式过程协同技术详解

    https://blog.51cto.com/zero01/2106494

  • 相关阅读:
    对健康的一些思考
    对提问的一些思考
    UVA 10118 Free Candies(免费糖果)(dp记忆化搜索)
    UVA 10285 Longest Run on a Snowboard(最长的滑雪路径)(dp记忆化搜索)
    UVA 12186 Another Crisis(工人的请愿书)(树形dp)
    UVA 10003 Cutting Sticks(切木棍)(dp)
    UVA 11584 Partitioning by Palindromes(划分成回文串)(dp)
    【洛谷P1144】最短路计数【最短路】
    【洛谷P1144】最短路计数【最短路】
    【洛谷P1144】最短路计数【最短路】
  • 原文地址:https://www.cnblogs.com/zjfjava/p/11909389.html
Copyright © 2011-2022 走看看