zookeeper 入门指导
- null字符串(\u0000)不能是一个路径名称。
- 下列字符不能使用,以为不能很好的被展示:\u0001-\u001F,\u007F-\u009F.
- 下列字符是不允许的:\ud800-uF8FF,\uFFF0-uFFFF.
- "."字符可以作为另一个名字被使用,但是“.”和“..”不能作为一个单独节点路径被使用,因为zookeeper不使用相对路径。下列是无效的:“a/b/./c”或者“a/b/../c”。
- “zookeeper”标记被保留。
- Zxid: ZooKeeper状态的每次变化都接收一个zxid(ZooKeeper事务id)形式的标记。这个展示了所有的ZooKeeper的变更顺序。每次变更会有一个唯一的zxid,如果zxid1小于zxid2说明zxid1在zxid2之前发生。
- Version numbers: 节点的每次变化都会引起这个节点版本号之一的一次增加。这三个版本号是:version(一个节点的数据变化次数),cversion(一个节点的子节点变化次数),aversion(一个节点的ACL 变化次数)。
- Tricks: 当使用多个ZooKeeper服务,服务器使用ticks来确定事件的时间,比如说状态上传、会话超时、连接超时等。这个tick时间仅仅通过最小会话超 时时间间接的暴露出来;如果一个客户端请求会话的超时时间小于最小超时时间,服务器将会告诉客户端实际的会话超时时间是最小超时时间。
- Real Time: ZooKeeper不使用实时、时钟时间。除了把时间戳放在stat结构中。
每个节点的Stat结构由下列字段组成:
- czxid:该数据节点被创建时的事务id。
- mzxid:该节点最后一次被更新时的事务id。
- ctime:节点被创建时的时间。
- mtime:节点最后一次被更新时的时间。
- version:这个节点的数据变化的次数。
- cversion:这个节点的子节点 变化次数。
- aversion:这个节点的ACL变化次数。
- ephemeralOwner:如果这个节点是临时节点,表示创建者的会话id。如果不是临时节点,这个值是0。
- dataLength:这个节点的数据长度。
- numChildren:这个节点的子节点个数。
为了创建一个客户端会话,应用程序代码必须提供一个连接字符串列表以逗号分隔开,主机:端口号成对出现,每个都相当于一个ZooKeeper服务器 (例如:”127.0.0.1:4545″ 或 “127.0.0.1:3000,127.0.0.1:3001,127.0.0.1:3002″)。
当一个客户端从ZooKeeper服务得到一个句柄,ZooKeeper创建了一个会话,表现为一个64位的数字,并把 它分配给客户端。如果客户端连接到一个不同的服务端,在连接握手的时候它将发送这个会话id。作为一个安全措施,服务端给会话id创建了一个密码,让服务 端能够校验。当客户端建立会话的时候,这个密码随着会话id一起发送给客户端。每当客户端与一个新的服务端恢复会话的时候,密码会随着会话id一起发送过 去。
当一个客户端从ZK服务集群成为分区,它将开始寻找在会话创建时期指定的服务端列表。最终,当客户端和至少一个服务端联通重新建立的时候,会话要么 转变成“connected”状态(如果在会话超时时间内恢复连接),要么转变成“expired”状态(如果在超时时间之外恢复连接)。在断开时创建一 个新的会话是不可取的。ZK客户端库将处理连接。尤其是客户端内部有方法来处理像“羊群效应”之类的事情。仅仅在你被通知会话过期的时候去创建一个新的会 话。
对于一个过期的会话,监听器所看到的状态转变:
- “connected”:会话被建立,并且客户端能和集群交流
- ……客户端从集群被分割
- “disconnected”:客户端与集群丢失了联系
- ……时间流逝,在超时时间之后,集群已经让这个会话过期,而客户端没看到什么,因为它已经从集群断开连接了
- ……时间流逝,客户端恢复网络和集群联通
- “expired”:最后客户端与集群重新连接,然后收到过期的通知
一旦成功建立一个到服务端的连接,当客户端发生connectionloss异常 时有两种基本的情况,在执行一个同步或者非同步的操作时:
- 应用调用一个操作,但是会话不再存活。
- 当等待一个操作的时候ZooKeeper客户端从服务端断开连接,比如说:等待一个异步调用。
另一个例子,假设我们有5个主机,然后现在更新列表移除两个主机,连接到剩余三台主机的客户端依然保持连接,然而所有连接到已被移除主机的客户端都 需要移到剩下三台主机的一台上,并且这种选择是随机的。如果连接断开,客户端进入一个特殊的模式并使用概率算法选择一个新的服务器,而不仅仅只是循环。
- 一次性触发:当数据改变的时候一个监听事件会被发送给客户端。比如说,如果一个客户端做了getData(“/znode1″, true)操作,然后 /znode1下的数据被改变或者删除了,客户端将得到/znode1的一个监听事件。如果/znode1节点再次发生改变,没有监听事件会被发送,除非客户端做了别的,设置了一个新的监听器。
- 发送到客户端:这意味着事件正在发送给客户端的途中,但是在操作成功的返回码到达发起这个变更操作的客户端之前,事件可能还没到达监听的客户端。 ZooKeeper提供了一个有序保证:在它第一次看到监听事件之前,它永远不会看到它设置的监听改变。网络延迟或别的因素,可能会引起不同的客户端看见监听器和更新操作的返回码,在不同的时间。关键得一点是不同的客户端看见的每件事有一个一致的顺序。
- 被设置监听的数据:这是指一个节点能变化的不同方式。可以认为ZooKeeper有两个监听器列表:数据监听和子节点监听。getData()和 exists()设置数据监听器。 getChildren()设置子节点监听器。二选一,根据返回数据的类型来设置监听器。getData()和exists()返回节点的数据信息,然而 getChildren()返回一个子节点列表。因此,setData()会触发数据监听器。一个成功的 create()会触发一个数据监听器。一个delete()会触发数据监听器和子节点监听器。
监听器的意思
- 创建事件:exists的调用
- 删除事件:exists,getData和getChildren的调用
- 改变事件:exists,getData的调用
- 子节点事件:getChildren的调用
移除监听器
- 子节点移除事件:调用getChildren增加的监听器。
- 数据移除事件:调用exists或getData增加的监听器。
ZooKeeper对监听器的保证
对于监听器,ZooKeeper有下列的保障:
- 监听器和另外的事件,另外的监听器和异步的回复是有序的。ZooKeeper 客户端库确保每件事都有序分发。
- 一个客户端看到这个节点的新的数据之前,会先看到他监听的节点的一个监听事件。
- 从ZooKeeper 来的监听事件的顺序对应于ZooKeeper 服务看到的更新的顺序。
- 监听器是一次触发的,如果你得到了一个监听事件并且想继续得到未来的事件通知,你必须设置一个另外的监听器。
- 因为监听器是一次触发的,就会在得到事件和发送请求设置新的监听器之间有一个延迟,你不能看到ZooKeeper的节点上每次 改变。准备好处理在得到事件和设置监听器之间节点多次改变的情况(你或许不太关心,但至少要意识这会发生)。
- 一个监听器对象或一个函数/上下文对,为一个事件只会被触发一次。比如说,如果相同的监听器在一次exists或getData调用中被注册到了相同的文件,并且文件被删除,对于该文件删除的通知,监听器对象只会被调用一次。
- 当你从服务器断开连接,在恢复连接之前,你不会得到任何监听器。由于这个原因,会话事件会被发送给所有的未处理的监听器。使用会话事件进入一个安全模式:在断开期间,你不会收到事件,所以你的进程在这种模式下应该小心行事。
ZooKeeper使用ACLs来控制访问它的节点(ZooKeeper数据树上的数据节点)。ACL的实现和UNIX文件访问权限非常相似:它使 用权限位来允许/拒绝对节点和位适用范围的各种操作。不像标准的UNIX权限,一个ZooKeeper节点没有限制在这三个标准的范围:user (文件拥有者)、group、world 。ZooKeeper没有节点拥有者的概念,取而代之的是,一个ACL指定ids和id相关的权限的集合。
还请注意一个ACL只适用于一个指定的节点,它也不适用于子节点。比如说,如果 /app节点只能被ip:172.16.16.1读取, /app/status是全部可读的,任何人都 可以读取/app/status。ACLs不是递归的。
ZooKeeper支持可插拔式的认证方案。Ids指定使用这个形式scheme:id,scheme是id对应的授权方案,比如说,ip:172.16.16.1是一个主机地址为172.16.16.1的id。
当一个客户端连接ZooKeeper并进行认证,ZooKeeper把符合这个客户端的所有ids联系起来。当客户端尝试存取一个节点的时候,这些ids用来检查一个节点的ACLs。ACLs由成对(scheme:expression, perms)的组成。expression的格式指定了权限,比如说,(ip:19.22.0.0/16, READ)给所有的以19.22开头的IP地址的客户端读的权限。
- CREATE:可以创建一个子节点
- READ:可以从一个节点读取数据并展示子节点
- WRITE:可以设置一个节点的数据
- DELETE:可以删除一个子节点
- ADMIN:可以设置权限