简而言之,ZooKeeper 可帮助您构建分布式应用程序。
工作原理
您可以将 ZooKeeper 描述为具有最终一致性的复制同步服务。它是健壮的,因为持久化的数据分布在多个节点之间(这组节点称为“集合”),并且一个客户端连接到其中的任何一个(即特定的“服务器”),如果一个节点发生故障则迁移;只要严格的大多数节点都在工作,ZooKeeper 节点的集合就是活着的。特别是,主节点是在集成中通过共识动态选择的;如果主节点发生故障,主节点的角色将迁移到另一个节点。
如何处理写入
master 是写入的权限:这样可以保证写入按顺序持久化,即写入是线性。每次客户端写入 ensemble 时,大多数节点都会保存信息:这些节点包括客户端的服务器,显然还有主节点。这意味着每次写入都会使服务器与主服务器保持同步。但是,这也意味着您不能进行并发写入。
线性写入的保证是 ZooKeeper 对于写入主导的工作负载表现不佳的原因。特别是,它不应该用于大数据的交换,例如媒体。只要您的通信涉及共享数据,ZooKeeper 就可以帮助您。当数据可以并发写入时,ZooKeeper 实际上会阻碍,因为它强制执行严格的操作顺序,即使从写入者的角度来看并非绝对必要。它的理想用途是协调,在客户端之间交换消息。
如何处理读取
这就是 ZooKeeper 擅长的地方:读取是并发的,因为它们由客户端连接的特定服务器提供服务。然而,这也是最终一致性的原因:客户端的“视图”可能已过时,因为主服务器更新相应的服务器时有一个有限但未定义的延迟。
详细说明
ZooKeeper 的复制数据库包含一棵 znodes 树,它们是大致代表文件系统节点的实体(将它们视为目录)。每个 znode 都可以通过存储数据的字节数组来丰富。此外,每个znode下可能还有其他znode,实际上形成了一个内部目录系统。
顺序znodes
有趣的是,一个znode的名字可以是sequential,这意味着客户端在创建znode时提供的名字只是一个前缀:全名也由一个序列号给出合奏。这很有用,例如,用于同步目的:如果多个客户端想要获得一个资源的锁,他们可以同时在一个位置上创建一个顺序 znode:获得最低编号的人有权获得锁。
临时znodes
此外,znode 可能是短暂的:这意味着一旦创建它的客户端断开连接,它就会被销毁。这主要用于了解客户端何时失败,这可能与客户端本身具有新客户端应承担的责任有关。以锁为例,一旦拥有锁的客户端断开连接,其他客户端就可以检查自己是否有权获得锁。
手表
如果我们需要定期轮询 znode 的状态,则与客户端断开相关的示例可能会出现问题。幸运的是,ZooKeeper 提供了一个事件系统,可以在 znode 上设置 watch。如果 znode 被专门更改或删除,或者在其下创建新的子节点,则这些监视可以设置为触发事件。与 znode 的顺序和临时选项结合使用时,这显然很有用。
在哪里以及如何使用它
Zookeeper 使用的典型示例是分布式内存计算,其中一些数据在客户端节点之间共享,并且必须以非常谨慎的方式访问/更新以考虑同步。
ZooKeeper 提供了用于构建同步原语的库,而运行分布式服务器的能力避免了使用集中式(类似代理)消息存储库时遇到的单点故障问题。
ZooKeeper 是轻量级的,这意味着领导者选举、锁、屏障等机制尚不存在,但可以在 ZooKeeper 原语之上编写。
如果 C/Java API 对于您的目的来说过于笨拙,您应该依赖构建在 ZooKeeper 上的库,例如 cages,尤其是 curator。
在哪里阅读更多
除了官方文档,还不错,我建议阅读Hadoop: The Definitive Guide 的第 14 章,其中有大约 35 页基本上解释了 ZooKeeper 的作用,然后是配置服务的示例。