食谱(recipes)
![ZooKeeper数据数结构](https://i-blog.csdnimg.cn/blog_migrate/a83a29a204190e2fb4641a25518cf584.png)
recipes是应用使用ZooKeeper提供的API作为原语的实现。recipes包含了ZooKeeper的操作,并且维护一个小型的数据节点,这些节点被称为znode。
上图描述了一个znode树的结构,根节点包含4个子节点,下面三个子节点包含下一级节点,叶子节点存储了数据信息。如果一个znode没有数据,那这代表着一些信息。在主从节点中,如果主节点的znode没有数据,表示当前还没有选举出主节点。上图涉及的一些其他znode节点在主-从模式的配置中很有用:
- ./workers节点下的每个znode子节点保存了系统中一个可用的从节点。(如:foo.com:2181)
- ./tasks节点下的每个znode子节点保存了一个可供从节点执行的任务。
- ./assign下的每个znode子节点保存了分配到某个从节点的一个任务信息。
简单API
ZooKeeper不允许局部写入或读取znode节点的数据,当设置一个znode节点的数据或读取时,znode节点的内容会被整个替换或全部读取进来。
- 创建一个名为/path的znode节点,并包含数据data:create/path data
- 删除名为/path的znode节点:delete/path
- 检查是否存在名为/path的节点:exists/path
- 设置名为/path的znode的数据为data:setData/path data
- 返回名为/path节点的数据信息:getData/path
- 返回所有/path节点的所有子节点列表:getChildren/path
znode类型
znode一共有四种类型:持久节点,临时节点,持久有序节点,临时有序节点。
1)持久节点和临时节点
持久的znode只能通过delete进行删除,而临时节点不同,当创建该节点的客户端崩溃或关闭了与ZooKeeper的连接时,这个节点就会被删除。
2)使用场景
持久节点:在主-从模式中,需要保存从节点的任务分配情况,即使分配任务的主节点已经崩溃了。
临时节点:主-从模式中,需要通过某个主节点创建的临时节点来检测主节点是否崩溃。当该节点存在,表示主节点正常运行,当主节点崩溃,这个节点需要和主节点一起消失。在从节点中也需要使用临时znode,如果一个从节点失效,那么会话将会过期,之后该节点也将自动消失。
3)有序节点
当一个znode被设置成有序的,系统会分配一个递增的整数,然后追加到路径之后。如创建znode路径为/tasks/task-,那么ZooKeeper将自动分配一个序号,如1,那么该节点最终的路径为/tasks/task-1。
监视与通知
ZooKeeper是通过通知机制来获取znode的状态变更的。客户端可以对znode设置监视点(watch)来获取通知,监视点是只能触发一次的,因此每次获取到通知后,客户端需要再次设置监视点。
假如在获取到通知与设置监视点之间,另一个客户端对该znode的状态进行了改变,那么该客户端只能在下一次通知时才能获取到这次改变。ZooKeeper为这种情况提供了一种机制,那就是在设置监视点之前,首先获取一下znode的最新状态(这里有些问题,获取最新状态和设置监视点是原子性的吗?如果不是那么仍然有问题,留到后续解决)。ZooKeeper不保证强一致性,只保证最终一致性。
版本号
每个znode都有一个版本号,随着数据变化自增。当客户端对znode进行操作时,需要传入版本号,当这个版本号与服务器上一致时,该客户端操作才能成功。
ZooKeeper架构
![ZooKeeper架构](https://i-blog.csdnimg.cn/blog_migrate/27aab6dee122eb45643ae56387e62e68.png)
独立模式:只有一个单独的服务器,ZooKeeper状态无法复制。
仲裁模式:具有一组ZooKeeper服务器,相互之间可以复制状态信息,并同时服务于客户端的请求。
ZooKeeper仲裁
如果每次客户端请求,都要等待所有服务器将状态保存,那么这造成的延迟是不能接受的。因此在ZooKeeper中,可以设置一个保存客户端数据的服务器最小个数——法定人数。例如当前有5台ZooKeeper服务器,但法定人数为3,只要任何3台服务器保存了数据,客户端就可以继续,其余两台最终也能完成状态信息保存。
法定人数确定原则:多数原则,奇数原则。
会话
客户端对连接到ZooKeeper服务器上时,会创建一个会话,所有操作都会关联在一个会话上,当一个会话终止时,在这个会话期间创建的临时节点将会消失。
客户端通过TCP协议与服务器进行连接并通信,当会话无法与当前连接的服务器继续进行通信时,会透明的将会话转移到其他服务器。
同一个会话保障请求的顺序,会以FIFO顺序执行。如果客户端有多个并发会话,多个会话的请求并不能保证顺序。