数据模型和分层的命名空间
Zookeeper提供的命名空间非常像一个标准的文件系统。一个名字是一系列的以'/'隔开的一个路径元素。Zookeeper命名空间中所有的节点都是通过路径识别。
节点和临时节点
不像标准的文件系统,Zookeeper命名空间中的每个节点可以有数据也可以有子目录。它就像一个既可以是文件也可以是目录的文件系统。(Zookeeper被设计成保存协调数据:状态信息,配置,位置信息,等等,所以每个节点存储的数据通常较小,通常在1个字节到数千字节的范围之内)我们使用术语znode来表明Zookeeper的数据节点。
znode维持了一个stat结构,它包括数据变化的版本号、访问控制列表变化、和时间戳,允许缓存验证和协调更新。每当znode的数据有变化,版本号就会增加。例如,每当客户端检索数据时同时它也获取数据的版本信息。版本号和时间戳一起,可让Zookeeper验证缓存和协调更新。每次znode的数据发生了变化,版本号就增加。例如,无论何时客户端检索数据,它也一起检索数据的版本号。并且当客户端执行更新或删除时,客户端必须提供他正在改变的znode的版本号。如果它提供的版本号和真实的数据版本号不一致,更新将会失败。(这种行为可以被覆盖)
命名空间中每个znode存储的数据自动的读取和写入的,读取时获得znode所有关联的数据字节,写入时替换所有的数据。每个节点都有一个访问控制列表来制约谁可以做什么。
Zookeeper还有一个临时节点的概念。这些znode和session存活的一样长,session创建时存活,当session结束,也跟着删除。
Zookeeper还有一个序列节点的概念。当创建znode的时候你还可以请求在路径的最后追加一个单调递增的计数器。这个计数器在父节点是唯一的。计数器有一个%010d --的格式,它是10位数用0做填充(计数器用这个方法格式化简化排序),也就是:0000000001。查看Queue Recipe使用这个特性的例子。注释:计数器的序列号由父节点通过一个int类型维护,计数器当超过2147483647的时候将会溢出(-2147483647将会导致)。
在分布式应用工程中,node可以指的是一般的主机,一个服务器,全体成员的一员,一个客户端程序,等等。在Zookeeper的文档中,znode指的是数据节点。Servers指的是组成Zookeeper服务的机器;quorum peers 指的是组成全体的servers;client指的是任何使用Zookeeper服务的主机和程序。
Zookeeper里的计时
Zookeeper通过多种方式追踪计时:
Zxid
每个Zookeeper状态的变化都以zxid(事务ID)的形式接收到标记。这个暴露了Zookeeper所有变化的总排序。每个变化都会有一个zxid,并且如果zxid1早于zxid2则zxid1一定小于zxid2。
zookeeper中,每一次对数据节点的写操作,都被认为是一次事务,每一事务,系统都会分配一个事务id(zxid)来标识这个事务
版本号
节点的每个变化都会引起那个节点的版本号的其中之一增加。这三个版本号是version(znode的数据变化版本号),cversion(子目录的变化版本号),和aversion(访问控制列表的变化版本号)。
Ticks
当使用多服务器的Zookeeper时,服务器使用ticks定义事件的时间,如状态上传,会话超时,同事之间的连接超时等等。tick次数只是通过最小的会话超时间接的暴露;如果一个客户端请求会话超时小于最小的会话超时,服务器就会告诉客户端会话超时实际上是最低会话超时时间。
Real time
Zookeeper不使用实时或时钟时间,除了将时间戳加在znode创建和更新的stat结构上。
Zookeeper Stat 结构
Zookeeper中的每个znode的stat机构都由下面的字段组成:
- czxid - 引起这个znode创建的zxid (括号内是我自己的理解 create zxid)
- mzxid - znode最后更新的zxid (modify zxid)
- ctime - znode被创建的毫秒数 -从1970年开始)
- mtime - znode最后修改的毫秒数 -从1970年开始)
- version - znode数据变化号
- cversion - znode子节点变化号 (change version)
- aversion - znode访问控制列表的变化号 (access version)
- ephemeralOwner - 如果是临时节点这个是znode拥有者的session id。如果不是临时节点则是0。
- dataLength - znode的数据长度
- numChildren - znode子节点数量
下面正式开始介绍zkCli.sh的使用
1.首先启动zk
bin/zkServer.sh start
2.建立连接
./zkCli.sh -timeout 0 -server ip:port
- timeout 会话的超时时间,如果服务器在这个timeout规定的时间范围内,没有收到心跳包,就认为失效了
./zkCli.sh -timeout 5000 -server 192.168.142.128:2181
出现如上图说明连接成功。
输入 h 查询所有的命令:
创建znode节点命令
其中 -e表示当前节点是临时节点,-s表示当前节点是序列节点。
我们创建一个基本节点
- ls指令
要查询是否创建成功,可以使用查询命令ls /
其中/
代表根节点
结果如下:
只输出了[zookeeper]说明刚才那个节点没有新建成功,检查一下。原来是忘了输入关联的数据(囧)
再输入一次:
后面的5就是关联的数据
如果 新建成功,也会打印出 ‘Created /node_1 ’
现在node_1新建成功了。
查询znode节点命令
- get指令
通过get命令检测数据是否与znode关联上了(数据就是我上面输入的5)
显示如下:
第二行的5就是关联的数据,下面的一些字段的含义可以参照前文的 Zookeeper Stat 结构
-
pZxid 指该节点子节点列表最后一次被修改的事务id。为当前节点添加子节点和删除子节点会引起子节点列表发生改变,而修改子节点的数据内容是不包括在内的。
-
aclVersion 是指权限版本号
-
stat 指令
还有一个命令类似,查看当前节点的状态信息,但是不能显示当前节点数据的值。如下:
为node_1创建两个子节点:
- ls2 指令
ls2指令是ls指定的加强版,除了可以列出当前节点的所有子节点,还可以输出当前节点的状态信息。
修改znode的命令
其中path是需要修改的节点的路径
data是需要修改成什么样的值
可选的version是版本号 我们先不输入版本号
注意到此时dataVersion是2(因为本人已经修改过一次了,这次属于第二次修改)
get一下
我们再修改一次,然后再get
我们可以发现,版本号自动加了1,说明每次修改节点,节点的版本号会增加。
然后 我们修改时加上版本号 再试一下
版本号先设为当前版本号:
发现修改成功,版本号也加了1
再设一次,此次将版本号还是设为3(dataVersion中已经是4了),然后查看结果:
提示版本号无效
删除相关指令
我们试着删除node_1
提示很明显,delete
指令不能删除含有子节点的节点,如果要删除含有子节点的节点,则需要使用命令rmr
删除后,无错误信息,说明删除成功,通过查看命令验证一下:
参考:
1.Zookeeper简介 http://zookeeper.majunwei.com/document/3.4.6/Overview.html
2.Zookeeper开发者编程指南 http://zookeeper.majunwei.com/document/3.4.6/DeveloperProgrammerGuide.html