写在前面
- 主机环境为Ubuntu(16.04.6)
- Zookeeper的版本号是3.04.10
- 如果本篇博客中有哪些地方说的不对,还请各位博主指出,感谢。
-------------------------------------------------------------------------------------------------------------------
zookeeper的节点管理方式
在Zookeeper这个组件中,保存数据是以节点的形式区进行存储的,Zookeeper采用类似于文件系统的层级树状结构进行管理,如下图所示:
从上图中我们发现有些node节点中是没有数据的值的,比如说/workers节点,其实没有数据往往传递了一种重要的信息,可以用来作为一种标志的节点,比如说:/tasks节点,在该节点下的所有子节点就可以表示为已经创建并等待执行任务的信息。
zookeeper的api概述
在Zookeeper中,并不会直接的暴露原语(创建,获取,释放等),他只是暴露了有一小部分调用方法组成的类似于文件系统的API,以便应用允许实现自己的原语。Zookeeper的API有以下几种:
常用的API:
create /path data
,创建一个名为/path的znode节点,并且设置初始值data,另外你也可以添加参数-s(持久化节点)或者-e(临时节点)去设置节点的类型,默认创建节点是持久化节点。get /path
,获取节点的信息,包含了当前节点的值,以及节点的一些基本的配置信息。data cZxid节点创建时的zxid ctime节点创建时间 mZxid节点最近一次更新时的zxid mtime节点最近一次更新的时间 pZxid是与该节点的子节点(或该节点)的最近一次创建/删除的时间戳 cversion子节点数据更新次数 dataVersion本节点数据更新次数 aclVersion节点ACL(授权信息)的更新次数 ephemeralOwner如果该节点为临时节点,ephemeralOwner值表示与该节点绑定的session id. 如果该节点不是临时节点,ephemeralOwner值为0 dataLength节点数据长度,本例中为hello world的长度 numChildren子节点个数
set /path data
,设置对应路径下znode节点的值。delete /path
,删除节点。
注意: Zookeeper不允许局部写入或者局部读取znode节点的数据,znode节点中的数据只能被全部读取或者全部替换。
zookeeper的节点类型
当我们新建zode节点的时候,我们可以指定不同的节点的类型,不同的节点的类型往往具有不一样的行为方式。
Zookeeper中节点的类型可以分为两大类,持久化节点和临时节点,持久话有序节点,临时有序节点。
- 持久化节点
这种节点我们从名字中就可以看出,这种类型的节点只能通过/delete
命令去删除。这种节点的好处就是我们可以持久话数据,当znode节点的创建者不属于这个系统的时候,数据也可以保存下来,不会丢失。 - 临时节点
与持久化节点刚刚相反,这种类型的节点一旦创建该节点的客户端崩溃或者与服务器端的链接断开时,这个节点就会被删除,如果其他的客户端调用删除的命令删除节点的时候,那么临时节点也是可以被删除的。这种节点既然被提出来肯定有它的意义,比如说我们可以用来标记应用的一些信息,在主从模式中,通过主节点创建一个临时节点用来标识主节点的运行状态,当主节点出现问题的时候,那么该临时节点也要消失,系统监视该临时节点,阻止继续运行。
注意: 由于临时节点在其创建者的会话过期时会被删除,所以目前不允许在临时节点下创建节点。 - 持久有序节点
在持久化节点的基础之上,会为每个节点后面追加一个序号,用来标识新创建的节点,这种方式我们可以直观的看出节点的创建顺序。 - 临时有序节点
同持久节有序节点的方式一样,在临时节点的基础之上加上一个序号。
Zookeeper的监视和通知机制
由于Zookeeper通常以远程服务的方式被访问,如果每次客户端访问znode去获取节点中的内容的时候,这样的代价就会比较大,会造成更更高的延迟,所以在zookeeper中,客户端获取节点的信息并没有采用轮询的方式,而是采用了基于通知的机制:客户端向Zookeeper注册需要接受通知的znode,通过对znode设置监视点来接受节点的信息。**注意:**监视点是一个单词触发的操作,也就是说一个监视点只能被使用一次,一旦使用之后,需要重新的设置监视点。如下图所示:
上图的过程:
1:客户端1请求命令getChildren /tasks
获取/tasks节点下的子节点,并且通过set watch
命令设置监视点
2:客户端2通过create /tasks/taks-1 data
命令在/tasks节点下创建了子节点task-1
3:由于客户端2创建了一个/tasks/task-1的原因,Zookeeper将通知客户端1节点/tasks下有子节点了,让客户端1来读取。
4:客户端1请求命令getChildren /tasks
获取/tasks节点下的子节点,并且通过set watch
命令设置监视点
5:将/tasks节点的子节点信息返回到客户端1中
通知机制的一个重要保障:当有数据在被监视的节点上更新的时候,Zookeeper会先通知客户端,然后才会对当前节点进行数据的变更。这样我们就可以保证了客户端以全局的顺序来观察Zookeeper中节点的变化。
Zookeeper的版本控制
在Zookeeper中,每一个znode节点都会绑定一个版本号,当客户端去更新节点中的数据的时候,会比较自身缓存的节点的版本号与zookeeoer中节点的版本号进行对比,如果一样的时候才能成功的将数据变更到对应的节点上。使用版本号这样的机制就是为了防止并发的时候数据的不一致性。