zookeeper基本特性与基于Linux的ZK客户端命令行学习

zookeeper常用命令行操作

  1. 通过 zkCli.sh 来打开zk客户端:
[[email protected] ~]# zkCli.sh
[zk: localhost:2181(CONNECTED) 0]
  1. ls 与 ls2 命令:
[zk: localhost:2181(CONNECTED) 0] ls /  # ls命令用于查看节点,类似于Linux中的查看目录
[zookeeper]
[zk: localhost:2181(CONNECTED) 1] 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) 2]
  1. get 与 stat命令:
[zk: localhost:2181(CONNECTED) 2] stat /  # stat命令用于查看节点状态的详细信息
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] get /  # get命令用于查看节点的数据以及节点状态的详细信息,由于没有数据所以这里显示的是空行

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) 4] 

关于节点状态属性信息的描述,如下表:

属性 描述
cZxid 节点的创建时间所对应的Zxid格式时间戳
ctime 节点的创建时间
mZxid 节点最后的修改时间所对应的Zxid格式时间戳
mtime 节点最后的的修改时间
pZxid 该节点的子节点(或该节点)的最近一次 创建 / 删除 所对应的Zxid格式时间戳
cversion 节点所拥有的子节点被修改的版本号,删除或添加子节点,版本号会自增
dataVersion 当前节点数据的版本号,数据写入操作,版本号会递增
aclVersion 节点ACL权限版本,权限写入操作,版本号会递增
ephemeralOwner 临时节点创建时的事务id,如果节点是永久节点,则它的值为0
dataLength 节点数据长度(单位:byte),中文占3个byte
numChildren 子节点数量

session的基本原理与create命令的使用

zk特性-session的基本原理:

  • 客户端与服务端之间的连接存在会话
  • 每个会话都可以设置一个超时时间
  • 心跳结束,session则过期
  • session过期,则临时节点znode会被抛弃
  • 心跳机制:客户端向服务端的ping包请求

create命令的使用:

[zk: localhost:2181(CONNECTED) 7] create /testDir test-data  # 创建一个节点,节点的数据为test-data
Created /testDir
[zk: localhost:2181(CONNECTED) 8] ls /
[zookeeper, testDir]
[zk: localhost:2181(CONNECTED) 9] get /testDir
test-data
cZxid = 0x4
ctime = Sun Apr 22 18:17:56 CST 2018
mZxid = 0x4
mtime = Sun Apr 22 18:17:56 CST 2018
pZxid = 0x4
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 9
numChildren = 0
[zk: localhost:2181(CONNECTED) 10]

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

[zk: localhost:2181(CONNECTED) 11] create -e /testDir/tmp tmp-data  # -e指定创建的节点是临时节点
Created /testDir/tmp
[zk: localhost:2181(CONNECTED) 12] get /testDir
test-data
cZxid = 0x4
ctime = Sun Apr 22 18:17:56 CST 2018
mZxid = 0x4
mtime = Sun Apr 22 18:17:56 CST 2018
pZxid = 0x5
cversion = 1  # 由于在testDir下创建了一个子节点,所以 cversion 的值就会进行累加
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0  # 表示持久节点
dataLength = 9
numChildren = 1
[zk: localhost:2181(CONNECTED) 16] get /testDir/tmp
tmp-data
cZxid = 0x5
ctime = Sun Apr 22 18:20:26 CST 2018
mZxid = 0x5
mtime = Sun Apr 22 18:20:26 CST 2018
pZxid = 0x5
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x10000052f5b0000  # 表示临时节点
dataLength = 8
numChildren = 0
[zk: localhost:2181(CONNECTED) 17] 

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

[zk: localhost:2181(CONNECTED) 17] quit  # 退出
Quitting...
2018-04-22 18:25:44,884 [myid:] - INFO  [main:[email protected]] - Session: 0x10000052f5b0000 closed  # session关闭了
2018-04-22 18:25:44,885 [myid:] - INFO  [main-EventThread:[email protected]] - EventThread shut down for session: 0x10000052f5b0000
[[email protected] ~]# zkCli.sh  # 重新连接服务端
[zk: localhost:2181(CONNECTED) 0] ls /testDir  # 可以看到,tmp节点就消失了
[]
[zk: localhost:2181(CONNECTED) 1]

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

[zk: localhost:2181(CONNECTED) 1] create -s /testDir/sec seq  # -s指定创建持久顺序节点
Created /testDir/sec0000000001  # 会自动为给定节点名加上一个数字后缀
[zk: localhost:2181(CONNECTED) 2] ls /testDir
[sec0000000001]
[zk: localhost:2181(CONNECTED) 3] create -s /testDir/sec seq
Created /testDir/sec0000000002  # 再次创建节点数字就会递增
[zk: localhost:2181(CONNECTED) 4] ls /testDir
[sec0000000001, sec0000000002]  # 这时就会有两个节点
[zk: localhost:2181(CONNECTED) 7] create -s /testDir/test seq  # 创建前缀不同的节点,数字也会递增
Created /testDir/test0000000003
[zk: localhost:2181(CONNECTED) 8] ls /testDir
[test0000000003, sec0000000001, sec0000000002]
[zk: localhost:2181(CONNECTED) 9] 

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

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

[zk: localhost:2181(CONNECTED) 15] create /testTmp testTmp-data  # 创建一个持久节点
Created /testTmp
[zk: localhost:2181(CONNECTED) 16] create -s -e /testTmp/secTmp secTmp-data  # 在该节点下,创建临时顺序节点
Created /testTmp/secTmp0000000000
[zk: localhost:2181(CONNECTED) 17] create -s -e /testTmp/secTmp secTmp-data
Created /testTmp/secTmp0000000001
[zk: localhost:2181(CONNECTED) 18] create -s -e /testTmp/testTmp secTmp-data
Created /testTmp/testTmp0000000002
[zk: localhost:2181(CONNECTED) 19] ls /testTmp
[testTmp0000000002, secTmp0000000001, secTmp0000000000]
[zk: localhost:2181(CONNECTED) 20]

断开客户端与服务端的连接,看看临时顺序节点是否会被清除:

[zk: localhost:2181(CONNECTED) 21] quit  # 退出
Quitting...
2018-04-22 19:07:13,527 [myid:] - INFO  [main:[email protected]] - Session: 0x10000052f5b0001 closed
2018-04-22 19:07:13,528 [myid:] - INFO  [main-EventThread:[email protected]] - EventThread shut down for session: 0x10000052f5b0001
[[email protected] ~]# zkCli.sh
[zk: localhost:2181(CONNECTED) 1] ls /testTmp  # 可以看到,节点都被清除了
[]
[zk: localhost:2181(CONNECTED) 2] 

set与delete命令的使用

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

[zk: localhost:2181(CONNECTED) 2] set /testDir new-data  # 修改testDir节点的数据
cZxid = 0x4
ctime = Sun Apr 22 18:17:56 CST 2018
mZxid = 0x12
mtime = Sun Apr 22 19:24:41 CST 2018
pZxid = 0xa
cversion = 5
dataVersion = 1
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 8
numChildren = 3
[zk: localhost:2181(CONNECTED) 3] get /testDir
new-data   # 可以看到数据更新了
cZxid = 0x4
ctime = Sun Apr 22 18:17:56 CST 2018
mZxid = 0x12
mtime = Sun Apr 22 19:24:41 CST 2018
pZxid = 0xa
cversion = 5
dataVersion = 1  # 此时数据版本就会递增为1
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 8
numChildren = 3
[zk: localhost:2181(CONNECTED) 4]

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

[zk: localhost:2181(CONNECTED) 4] set /testDir OneVerstion-data 1  指定版本去修改数据
cZxid = 0x4
ctime = Sun Apr 22 18:17:56 CST 2018
mZxid = 0x13
mtime = Sun Apr 22 19:29:29 CST 2018
pZxid = 0xa
cversion = 5
dataVersion = 2
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 16
numChildren = 3
[zk: localhost:2181(CONNECTED) 5] set /testDir OneVerstion-data 1  # 如果此时别人再次使用版本1去修改数据,就会报错
version No is not valid : /testDir
[zk: localhost:2181(CONNECTED) 6] 

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

[zk: localhost:2181(CONNECTED) 8] ls /testDir
[test0000000003, sec0000000001, sec0000000002]
[zk: localhost:2181(CONNECTED) 9] delete /testDir/sec0000000001  # 删除节点
[zk: localhost:2181(CONNECTED) 10] ls /testDir
[test0000000003, sec0000000002]
[zk: localhost:2181(CONNECTED) 11] delete /testDir/sec0000000002 0  # 通过指定版本号来删除节点
[zk: localhost:2181(CONNECTED) 12] ls /testDir
[test0000000003]
[zk: localhost:2181(CONNECTED) 13]

watcher机制

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

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

父节点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]

子节点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] 

原文地址:http://blog.51cto.com/zero01/2106494

时间: 2024-08-08 02:39:49

zookeeper基本特性与基于Linux的ZK客户端命令行学习的相关文章

【No.2】监控Linux性能25个命令行工具

接着上一篇博文继续 [No.1]监控Linux性能25个命令行工具 10:mpstat -- 显示每个CPU的占用情况 该命令可以显示每个CPU的占用情况,如果有一个CPU占用率特别高,那么有可能是一个单线程应用程序引起的 mpstat -P ALL 1 Linux 3.13.0-75-generic (lnmp)  06/25/2016  _x86_64_ (2 CPU) 02:28:59 PM  CPU    %usr   %nice    %sys %iowait    %irq   %s

ZooKeeper客户端命令行操作

ZooKeeper客户端命令行操作 启动服务端 [[email protected] zookeeper-3.4.10]$ bin/zkServer.sh start 查看状态信息 Using config: /opt/module/zookeeper-3.4.10/bin/../conf/zoo.cfg Starting zookeeper ... STARTED [[email protected] zookeeper-3.4.10]$ bin/zkServer.sh status ZooK

Linux服务器通过aws命令行上传文件至S3

目的Linux服务器通过AWS命令行上传文件至S3 配置打开你的AWS控制台: 连接你的Linux服务器,按照以下步骤操作: # 安装pip yum -y install python-pip   # 安装awscli pip install awscli   # 初始化配置 aws configure # 做这一步时系统会要求你输入"访问密钥ID"."私有访问密钥"."默认区域名称"."默认输出格式",前两个在创建IAM用户

linux命令行学习-dig(DNS查询器)

在web开发中,总要熟悉的就是http协议,而发起一个http开始前最先要经历的一个过程就是DNS解析.简单说就是域名如何最终解析到实际服务器ip的过程. 而在研究DNS解析和排除DNS解析类故障问题的时候一个强大的工具就是dig.和他对应的有个比较传统的命令nslookup,不过dig作为更新的命令,其强大而简洁可定制的输出也使得运维其开发人员使用. 实例1(访问服务器本地DNSserver查询根域名服务器):  ~#: dig ; <<>> DiG 9.3.6-P1-RedHa

Linux 操作MySQL常用命令行

Linux 操作MySQL常用命令行 注意:MySQL中每个命令后都要以分号:结尾. 1.显示数据库 mysql> show databases; +----------+ | Database | +----------+ | mysql | | test | +----------+ 2 rows in set (0.04 sec) Mysql刚安装完有两个数据库:mysql和test.mysql库非常重要,它里面有MySQL的系统信息,我们改密码和新增用户,实际上就是用这个库中的相关表进行

Linux中mysql进入命令行报错:MYSQL ERROR 2003 (HY000): Can&#39;t connect to MySQL server on &#39;192.168.99.192&#39; (111)

场景:在Linux中安装mysql01和mysql02,通过VIP虚出一个VIP=192.168.99.192,mysql01为主ip为192.168.99.153,mysql02为备机ip为192.168.99.154 此时VIP在mysql01上通过 mysql01上连接VIP :mysql -h 192.168.99.192 -P 3306   结果是可以正常进入mysql命令行: 通过mysql02上远程连接VIP 会在界面上报错:mysql error 2003(HY000):Can'

显示器 Linux 性能 18 (一个命令行工具传递)

对于系统和网络管理员来说每天监控和调试Linux系统的性能问题是一项繁重的工作.在IT领域作为一名Linux系统的管理员工作5年后,我逐渐认识到监控和保持系统启动并执行是多么的不easy.基于此原因.我们已编写了最常使用的18个命令行工具列表,这些工具将有助于每一个Linux/Unix 系统管理员的工作.这些命令行工具能够在各种Linux系统下使用.能够用于监控和查找产生性能问题的解决办法.这个命令行工具列表提供了足够的工具.您能够挑选适用于您的监控场景的工具. 1.Top-Linux进程监控

Linux上超酷的命令行扩展工具Oh My Zsh

Oh My Zsh 是一款社区驱动的命令行工具,正如它的主页上说的,Oh My Zsh 是一种生活方式.它基于 zsh 命令行,提供了主题配置,插件机制,已经内置的便捷操作.给我们一种全新的方式使用命令行. 什么是 Oh My ZshOh My Zsh 这个名字听起来就很有意思~, 它是基于 zsh 命令行的一个扩展工具集,提供了丰富的扩展功能. Oh My Zsh 的主页上,对它的定义有了明确的解释:http://ohmyz.sh 关于 zsh,它是一种命令行程序.我们 MAC 系统上默认使用

【Linux基础】Linux基础命令行学习笔记

绝对路径:cd /home/python相对路径:cd Downloads . 表示:当前那路径..表示:当前路径的上一层../.. 表示:当前路径的上二层 没有...或者以上的 ls: ls 查看当前路径下的文件以及文件夹的名字 ls /bin 表示:查看根目录下的bin文件夹下的东西 ls Documents 表示:查看当前路径下的Documents文件夹下的所有东西 ls *: * 表示任意多个字符,也可以没有 ? 表示一个字符,一定有1个,不能没有 [xn] 表示:中括号中的任意一个字符