前面介绍了ZooKeeper的一些基本特性,ZooKeeper入门,也安装运行了一个简单的ZooKeeper的例子。这此主要介绍ZooKeeper内部的一些工作方式理论部分。
主要涉及以下:
- ZooKeeper服务的架构
- ZooKeeper的数据模型
- ZooKeeper的节点特性
- ZooKeeper的访问控制
- Watcher(监听器)
ZooKeeper服务概览
ZooKeeper是一个复制式的分布式应用,有点像DNS服务或一些中心化的服务。
这是官网给的ZooKeeper服务图,所有组成ZooKeeper服务的服务器都相互知晓,它们维护了一个内存状态的镜像,也包含事务日志,持久存储的快照等。只要半数以上的的服务器是可用的,ZooKeeper服务就是可用的。
顺便提一下ZooKeeper的设计目标(Design Goals)
- 简单
- 复制式的 所有节点相互复制状态
- 有序的,所有的事务都有时间戳
- 快速 在读大于写的时候...
ZooKeeper在读数据的时候可以直接从当前节点读取数据,在写数据的时候需要将写请求转发到Leader节点上。
ZooKeeper数据模型
ZooKeeper的各个服务器节点共同维护一个可以注册数据的层级结构,类似于Unix的文件系统。数据注册的位置也称为znode
。
注意:
- 数据节点一般以字节形式存储,节点存储的数据大小最大不超过1MB。协作的数据一般不会太大。最好让数据远小于1MB会好些。
- ZooKeeper无法识别相对路径。 znode的路径必须是绝对路径
- 每个Znode除了存储数据以外,还有维护一些状态信息。
Znode 特性
Znode类型
ZooKeeper主要有两种节点类型,也可以说是三种。持久节点,临时节点。第三个是顺序节点,顺序节点也可以说是刚才那两种节点。 持久节点和顺序节点都可以是顺序节点。
注意节点的类型是在创建的时候就设置好的。
- 持久节点。ZooKeeper中最常见的一种节点类型,创建之后一直存在服务器上,知道有删除操作来主动清楚这个节点
- 临时节点,与客户端会话绑定在一起。 客户端会话失效,节点自动清理。(网络突然坏掉不算会话失效)
- 顺序节点,在节点创建的时候,ZooKeeper自动给节点名分配一个序列号。例如/path/to/znode-0000000001,一般是10位数字,序号之外的位以0填充。
节点状态
每一个Znode都有对应的stat结构,和文件系统类似。stat状态主要包含下面的信息:
- cZxid. 节点被创建时候的事务ID
- mZxid 节点最后一次被修改时候的事务ID
- pZxid 该节点的子节点最后一次被修改时的事务ID。子节点删除或添加才会影响pZxid
- ctime 节点被创建的时间
- mtime 节点被修改的世界
- dataVersion 这个节点数据改变的次数
- cversion 子节点被改变的次数
- aclVersion 节点的ACL(访问控制列表被改变的次数)
- ephemeralOwner 创建该临时节点的 session ID。如果是持久节点,设置为0
- dataLength 数据内容长度
- numChildren 当前节点子节点的个数
可以使用ls2
和stat
命令查看ZooKeeper节点下的信息。
ZooKeeper的访问控制(ACL)
ZooKeeper的数据模型提供了ACL来控制znode节点的访问。如果一个客户端符合ACL控制,那么就可以对其进行访问,否则将无法操作。
Zookeeper支持可配置的认证机制。它利用一个三元组来定义客户端的访问权限:
(scheme:expression, perms) 。其中:
- Schema 代表权限控制模式,分别为
- World 任何人
- Auth 不需要ID
- Digest 用户名和密码方式的认证
- IP Address IP地址方式的认证
- perms(权限),ZooKeeper支持如下权限
- CREATE: 创建子节点
- READ: 获取子节点与自身节点的数据信息
- WRITE:在Znode节点上写数据
- DELETE:删除子节点
- ADMIN:设置ACL权限
贴上如下图,在下次使用ZooKeeper的时候更明白,这次我们主要说明一些ZooKeeper理论方面的知识,具体编程的实现下次再说。
权限模式和授权对象的关系:
- IP: 通常是IP地址或是IP端,例如"192.168.1.2"或"192.168.1.1/24"
- Degist: 自定义,通常是"username:BASE64(SHA-1(username:password))"
- World:只有一个ID,“anyone”
- Super: 与Degist模式一致
注意:
- Znode的Acl只是针对某个节点,不会作用到它的子节点上
- 任何连接到ZooKeeper的客户端都可以使用exist操作,exist是不需要权限的。
ZooKeeper的Watcher
ZooKeeper中引入了Watcher机制来实现分布式通知功能,ZooKeeper允许客户端像服务端注册一个Watcher监听,当服务端的一些指定事件触发了这个Watcher,那么就会向指定客户端发送一个事件通知来实现分布式的通知功能。
有如下的Watcher事件类型可能出现:
- NodeChildrenChanged: zNode的子节点创建或删除的时候
- NodeCreated: 新的Znode节点被创建的时候
- NodeDataChanged: Znode节点的数据改变了的时候
- NodeDeleted: Znode节点被删除的时候。
关于Watcher内部实现机制,下次可以通过分析其源码进行更详细的说明
最后
这次主要介绍了一些ZooKeeper内部的基本概念,理论部分较多,若无理论的基础实施接下来的操作也不太方便。
接下来我会写下:
- ZooKeeper 客户端编程
- ZooKeeper Watcher监听器原理分析
参考
- 《从Paxos到ZooKeeper-分布式一致性原理与实践》
- 《Apache ZooKeeper Essential》
- ZooKeeper Overview