我试图了解 ZooKeeper,它是如何工作的以及它的作用。有没有可以与 ZooKeeper 相媲美的应用程序?
如果你知道,那么你会如何向外行描述 ZooKeeper?
我已经尝试过 apache wiki、zookeeper sourceforge ......但我仍然无法与它联系起来。
我刚刚通读了http://zookeeper.sourceforge.net/index.sf.shtml,难道没有更多这样的服务吗?只是复制一个服务器服务那么简单吗?
简而言之,ZooKeeper 可以帮助您构建分布式应用程序。
这个怎么运作
您可以将 ZooKeeper 描述为具有最终一致性的复制同步服务。它是健壮的,因为持久化的数据分布在多个节点之间(这组节点称为“集合”),并且一个客户端连接到其中的任何一个(即特定的“服务器”),如果一个节点发生故障则迁移;只要严格的大多数节点都在工作,ZooKeeper 节点的集合就是活着的。特别是,主节点是在集成中通过共识动态选择的;如果主节点发生故障,主节点的角色将迁移到另一个节点。
如何处理写入
master 是写入的权限:这样可以保证写入是按顺序持久化的,即写入是线性的。每次客户端写入 ensemble 时,大多数节点都会保存信息:这些节点包括客户端的服务器,显然还有主节点。这意味着每次写入都会使服务器与主服务器保持同步。但是,这也意味着您不能进行并发写入。
线性写入的保证是 ZooKeeper 对于写入主导的工作负载表现不佳的原因。特别是,它不应该用于大数据的交换,例如媒体。只要您的通信涉及共享数据,ZooKeeper 就可以帮助您。当数据可以并发写入时,ZooKeeper 实际上会阻碍,因为它强制执行严格的操作顺序,即使从写入者的角度来看并非绝对必要。它的理想用途是协调,在客户端之间交换消息。
如何处理读取
这就是 ZooKeeper 擅长的地方:读取是并发的,因为它们由客户端连接到的特定服务器提供服务。然而,这也是最终一致性的原因:客户端的“视图”可能已过时,因为主服务器以有限但未定义的延迟更新相应的服务器。
详细地
ZooKeeper 的复制数据库包含一个 znode 树,它们是大致代表文件系统节点的实体(将它们视为目录)。每个 znode 都可以通过存储数据的字节数组来丰富。此外,每个znode下可能还有其他znode,实际上形成了一个内部目录系统。
顺序znode
有趣的是,znode 的名称可以是连续的,这意味着客户端在创建 znode 时提供的名称只是一个前缀:全名也由集成选择的序号给出。这很有用,例如,用于同步目的:如果多个客户端想要获得一个资源的锁,他们可以同时在一个位置上创建一个顺序 znode:获得最低编号的人有权获得锁。
临时znode
此外,znode 可能是短暂的:这意味着一旦创建它的客户端断开连接,它就会被销毁。这主要用于了解客户端何时失败,这可能与客户端本身具有新客户端应承担的责任有关。以锁为例,一旦拥有锁的客户端断开连接,其他客户端就可以检查自己是否有权获得锁。
手表
如果我们需要定期轮询 znode 的状态,则与客户端断开相关的示例可能会出现问题。幸运的是,ZooKeeper 提供了一个事件系统,可以在 znode 上设置监视。如果 znode 被专门更改或删除,或者在其下创建新的子节点,则这些监视可以设置为触发事件。与 znode 的顺序和临时选项结合使用时,这显然很有用。
在哪里以及如何使用它
Zookeeper 使用的典型示例是分布式内存计算,其中一些数据在客户端节点之间共享,并且必须以非常谨慎的方式访问/更新以考虑同步。
ZooKeeper 提供库来构建您的同步原语,而运行分布式服务器的能力避免了您在使用集中式(类似代理)消息存储库时遇到的单点故障问题。
ZooKeeper 是轻量级的,这意味着领导者选举、锁、屏障等机制尚不存在,但可以在 ZooKeeper 原语之上编写。如果 C/Java API 对于您的目的来说过于笨拙,您应该依赖构建在 ZooKeeper 上的库,例如 cages,尤其是 curator。
在哪里阅读更多
除了官方文档,这很好,我建议阅读 Hadoop: The Definitive Guide 的第 14 章,其中有大约 35 页基本上解释了 ZooKeeper 的作用,然后是配置服务的示例。
Zookeeper 是最好的开源服务器和服务之一,有助于可靠地协调分布式进程。 Zookeeper 是一个提供一致性和分区容错性的 CP 系统(请参阅 CAP 定理)。 Zookeeper 状态跨所有节点的复制使其成为最终一致的分布式服务。
Moreover, any newly elected leader will update its followers with missing proposals or with a snapshot of the state, if the followers have many proposals missing.
Zookeeper 还提供了一个非常易于使用的 API。如果您正在寻找示例,这篇博文 Zookeeper Java API examples 提供了一些示例。
那么我们在哪里使用它呢?如果您的分布式服务需要集中、可靠和一致的配置管理、锁、队列等,您会发现 Zookeeper 是一个可靠的选择。
我总体上了解 ZooKeeper,但对“法定人数”和“脑裂”这两个术语有疑问,所以也许我可以与您分享我的发现(我认为自己也是外行)。
假设我们有一个包含 5 个服务器的 ZooKeeper 集群。其中一台服务器将成为领导者,其他服务器将成为追随者。
这 5 台服务器构成一个仲裁。 Quorum 仅仅意味着“这些服务器可以投票决定谁应该成为领导者”。
所以投票是基于多数。多数只是意味着“超过一半”,因此必须有超过一半的服务器同意特定服务器成为领导者。
因此,可能会发生这种不好的事情,称为“裂脑”。据我了解,脑裂就是这样:由 5 台服务器组成的集群分为两部分,或者我们称其为“服务器团队”,其中一部分可能是 2 台服务器,另一部分是 3 台服务器。这真是一个糟糕的情况,好像两个“服务器团队”都必须执行特定的命令,您将如何决定应该首选哪个团队?他们可能从客户那里收到了不同的信息。因此,了解哪些“服务器团队”仍然相关以及可以/应该忽略哪些是非常重要的。
多数也是您应该使用奇数服务器的原因。如果您有 4 台服务器和 2 台服务器分开的脑裂,那么两个“服务器团队”都可以说“嘿,我们要决定谁是领导者!”但是您应该如何决定应该选择哪 2 台服务器呢?使用 5 台服务器很简单:拥有 3 台服务器的服务器团队占多数,可以选择新的领导者。
即使您只有 3 台服务器,其中一台出现故障,另外 2 台仍然占多数,并且可以同意其中一台将成为新的领导者。
我意识到,一旦您考虑了一段时间并理解了这些术语,它就不再那么复杂了。我希望这也有助于任何人理解这些术语。
Zookeeper 是一个集中的开源服务器,用于维护和管理分布式集群环境的配置信息、命名约定和同步。 Zookeeper 通过提供低延迟和高可用性来帮助分布式系统降低管理复杂性。 Zookeeper 最初是 Hadoop 的一个子项目,但现在它是 Apache 软件基金会的顶级独立项目。
它解决了什么问题?
假设我们在文件存储中有一百万个文件,并且文件数量每天每分钟都在增加。我们的任务是首先处理然后删除这些文件。我们可以想到的一种方法是编写一个脚本来执行此任务并在多个服务器上并行运行多个实例。我们甚至可以根据需求增加或减少服务器数量。这基本上是一个分布式计算/数据处理应用程序。
在这里,我们怎样才能保证同一个文件不会被多个服务器同时拾取和处理呢?为了解决这个问题,所有服务器都应该共享关于当前正在处理哪个文件的信息。
这是我们可以使用 ZooKeeper 之类的东西的地方。当第一台服务器要读取文件时,它可以将要处理的文件名写入 zookeeper。现在其余的服务器可以查找 ZooKeeper 并知道该文件已被第一台服务器拾取。
上面是一个粗略的例子,需要很少的其他护栏,但我希望它可以让我们了解 zookeeper 是什么。 ZK 基本上是一个可以使用 ZK API 访问的数据存储。但它不应该用作数据库。只应存储少量数据(通常以 KB 为单位)。每个 znode 的上限为 1MB。 ZK 是专门构建的,以便分布式应用程序可以相互通信。
ZK的应用
开箱即用可用于
存储配置:存储跨分布式应用程序访问的配置。
命名服务:将服务名称和IP地址映射等信息存储在一个中心位置,使用户和应用程序可以跨网络进行通信。
组成员身份:所有运行在分布式服务器上的应用程序都可以连接到 ZK 并发送心跳。如果任何一个服务器/应用程序出现故障,那么 ZK 可以就此事件向其他服务器/应用程序发出警报。
其他功能必须建立在 ZooKeeper API 之上。
锁和队列——对分布式同步很有用。
两阶段提交 - 当我们必须跨服务器提交/回滚时很有用。
领导者选举 - 您的分布式应用程序可以使用 ZK 来举行领导者选举以实现自动故障转移。
共享计数器
下面是解释如何实现这些功能的页面https://zookeeper.apache.org/doc/current/recipes.html
ZooKeeper 可以有更多的应用程序。这些功能必须根据分布式系统的要求构建在 ZK API 之上。
注意:ZK 不应用于存储大量数据。它不是缓存/数据库。使用它来交换您的分布式应用程序启动、操作和故障转移所需的一小部分信息。
数据如何存储?
数据存储在分层树数据结构中。树中的每个节点称为znode。 znode 的最大大小为 1MB。 znodes 可以有数据和其他子 znodes。将 znode 想象成计算机上的一个文件夹,该文件夹可以包含包含数据的文件,但文件夹本身也可以像文件一样包含数据。
为什么要使用 ZK 而不是我们自己的自定义服务?
原子性和持久性
Zookeeper 本身是分布式和容错的。该架构涉及一个领导节点和多个跟随节点。如果 ZK 跟随者节点出现故障,它将自动进行故障转移。客户端会话被复制,因此 ZK 可以自动将客户端移动到不同的节点。如果 Leader 节点宕机,则使用 ZK 共识算法选出新的 Leader。
读取速度非常快,因为它是从内存存储中提供的。
写入是按照它到达的顺序写入的。因此保持有序。
手表会向设置手表的客户发送通知。这减少了轮询 ZK 的需要。请注意,手表是一次性触发器,如果您收到手表事件并且希望收到有关未来更改的通知,则必须设置另一个手表。
持久和临时 znode 可用。两者都存储在 ZK 磁盘上。这里的持久化意味着一旦创建它的客户端断开连接,数据就会被持久化。 Ephemeral 意味着当客户端断开连接时数据将被自动删除。临时 znode 不允许有子节点。
还有持久的顺序和短暂的顺序znode。这里 znode 的名称可以有一个后缀序列号。类似于 DB 自增 ID,这些序列号不断增加并由 ZK 管理。这对于实现队列、锁等很有用。
有没有可以和 Zookeeper 相媲美的应用?
etcd - https://etcd.io/docs/v3.3/learning/why/#zookeeper
我建议以下资源:
论文:https://pdos.csail.mit.edu/6.824/papers/zookeeper.pdf MIT 6.824 36:00 提供的讲座:https://youtu.be/pbmyrNjzdDk?t=2198
我建议观看视频,阅读论文,然后再观看视频。如果你事先了解 Raft 会更容易理解。
我理解 zookeeper 的方法是使用 CLI 客户端。如 Getting Started Guide 和 Command line interface 中所述
由此我了解到,zookeeper 的表面看起来非常类似于文件系统,客户端可以创建和删除对象以及读取或写入数据。
示例 CLI 命令
create /myfirstnode mydata
ls /
get /myfirstnode
delete /myfirstnode
自己试试
如何在几分钟内为 windows、linux 或 mac 在 docker 上启动 zookeper 环境:
一次性设置:
docker network create dn
在终端窗口中运行服务器:
docker run --network dn --name zook -d zookeeper
docker logs -f zookeeper
在第二个终端窗口中运行客户端:
docker run -it --rm --network dn zookeeper zkCli.sh -server zook
另请参阅documentation of image on dockerhub
Apache ZooKeeper 是一种开源技术,用于协调和管理分布式应用程序中的配置。它简化了维护配置详细信息、启用分布式同步和管理命名注册表等任务。
它的名字恰如其分——想想动物园管理员如何四处走动,照顾所有动物,维护它们的围栏,喂它们等等。
Apache ZooKeeper 可以与 Apache Pinot 或 Apache Flink 等 Apache 项目一起使用。 Apache Kafka 还使用 ZooKeeper 来管理代理、主题和分区信息。由于 Apache ZooKeeper 开源,您还可以将其与您选择的任何技术/项目配对,而不仅仅是 Apache Foundation 项目。