ZooKeeper概述适用于客户端开发人员,管理员和贡献者的技术概述文档
概述-ZooKeeper的鸟瞰图,包括设计概念和体系结构入门-教程风格的指南,供开发人员安装,运行和编程到ZooKeeper发行说明-开发人员和面向用户的新功能,改进和不兼容
目录
ZooKeeper:概述
ZooKeeper:分布式应用程序的分布式协调服务
设计目标
数据模型和分层名称空间
节点和短暂节点
有条件的更新和监视
保证金
简单的API
实作
用途
性能
可靠性
ZooKeeper项目
ZooKeeper入门指南
入门:使用ZooKeeper协调分布式应用程序
先决条件
下载
独立运行
管理ZooKeeper存储
连接到ZooKeeper
编程到ZooKeeper
运行复制的ZooKeeper
其他优化
发行说明-ZooKeeper
改善
任务
子任务
ZooKeeper:概述
/doc/current/zookeeperOver.html
ZooKeeper:分布式应用程序的分布式协调服务
ZooKeeper是用于分布式应用程序的分布式,开放源代码协调服务。它公开了一组简单的原语,分布式应用程序可以基于这些原语来实现用于同步,配置维护以及组和命名的更高级别的服务。它的设计易于编程,并使用了按照文件系统熟悉的目录树结构样式设置的数据模型。它以Java运行,并且具有Java和C的绑定。
众所周知,协调服务很难做到。它们特别容易出现诸如竞争条件和死锁之类的错误。ZooKeeper背后的动机是减轻分布式应用程序从头开始实施协调服务的责任。
设计目标
ZooKeeper很简单。ZooKeeper允许分布式进程通过共享的分层名称空间相互协调,该命名空间的组织方式类似于标准文件系统。名称空间由数据寄存器(在ZooKeeper看来,称为znode)组成,它们类似于文件和目录。与设计用于存储的典型文件系统不同,ZooKeeper数据保留在内存中,这意味着ZooKeeper可以实现高吞吐量和低延迟数。
ZooKeeper实施对高性能,高可用性,严格有序访问加以重视。ZooKeeper的性能方面意味着它可以在大型分布式系统中使用。可靠性方面使它不会成为单点故障。严格的排序意味着可以在客户端上实现复杂的同步原语。
ZooKeeper已复制。像它协调的分布式进程一样,ZooKeeper本身也可以在称为集合的一组主机上进行复制。
组成ZooKeeper服务的服务器都必须彼此了解。它们维护内存中的状态图像,以及持久存储中的事务日志和快照。只要大多数服务器可用,ZooKeeper服务将可用。
客户端连接到单个ZooKeeper服务器。客户端维护一个TCP连接,通过该连接发送请求,获取响应,获取监视事件并发送心跳。如果与服务器的TCP连接断开,则客户端将连接到其他服务器。
ZooKeeper已订购。ZooKeeper用一个反映所有ZooKeeper事务顺序的数字标记每个更新。后续操作可以使用该命令来实现更高级别的抽象,例如同步原语。
ZooKeeper很快。在“读取为主”的工作负载中,它特别快。ZooKeeper应用程序可在数千台计算机上运行,并且在读取比写入更常见的情况下,其性能最佳,比率约为10:1。
数据模型和分层名称空间
ZooKeeper提供的名称空间与标准文件系统的名称空间非常相似。名称是由斜杠(/)分隔的一系列路径元素。ZooKeeper命名空间中的每个节点均由路径标识。
ZooKeeper的层次命名空间
节点和短暂节点
与标准文件系统不同,ZooKeeper命名空间中的每个节点都可以具有与其关联的数据以及子节点。就像拥有一个文件系统一样,该文件系统也允许文件成为目录。(ZooKeeper旨在存储协调数据:状态信息,配置,位置信息等,因此存储在每个节点上的数据通常很小,在字节到千字节范围内。)我们使用术语znode来明确表示在谈论ZooKeeper数据节点。
Znodes维护一个统计信息结构,其中包括用于数据更改,ACL更改和时间戳的版本号,以允许进行缓存验证和协调更新。znode的数据每次更改时,版本号都会增加。例如,每当客户端检索数据时,它也会接收数据的版本。
原子地读取和写入存储在名称空间中每个znode上的数据。读取将获取与znode关联的所有数据字节,而写入将替换所有数据。每个节点都有一个访问控制列表(ACL),用于限制谁可以做什么。
ZooKeeper还具有短暂节点的概念。只要创建znode的会话处于活动状态,这些znode就存在。会话结束时,将删除znode。
有条件的更新和监视
ZooKeeper支持手表的概念。客户端可以在znode上设置手表。znode更改时,将触发并删除监视。触发监视后,客户端会收到一个数据包,说明znode已更改。如果客户端与ZooKeeper服务器之一之间的连接断开,则客户端将收到本地通知。
3.6.0中的新增功能:客户端还可以在znode上设置永久性的递归监视,这些监视在触发时不会删除,并且会以递归方式触发已注册znode以及所有子znode的更改。
保证金
ZooKeeper非常快速且非常简单。但是,由于其目标是作为构建更复杂的服务(例如同步)的基础,因此它提供了一组保证。这些是:
顺序一致性-来自客户端的更新将按照发送的顺序应用。原子性-更新成功或失败。没有部分结果。单个系统映像-无论客户端连接到哪个服务器,客户端都将看到相同的服务视图。也就是说,即使客户端故障转移到具有相同会话的其他服务器,客户端也永远不会看到系统的较旧视图。可靠性-应用更新后,此更新将一直持续到客户端覆盖更新为止。及时性-确保系统的客户视图在特定时间范围内是最新的。
简单的API
ZooKeeper的设计目标之一是提供一个非常简单的编程界面。因此,它仅支持以下操作:
create:在树中的某个位置创建一个节点
delete:删除节点
存在:测试某个位置是否存在节点
获取数据:从节点读取数据
设置数据:将数据写入节点
获取子节点:获取节点子节点的列表
sync:等待数据传播
实作
ZooKeeper组件显示了ZooKeeper服务的高级组件。除请求处理器外,构成ZooKeeper服务的每个服务器都复制其自己的每个组件副本。
复制的数据库是包含整个数据树的内存数据库。更新被记录到磁盘以确保可恢复性,并且在将写入应用于内存数据库之前将写入序列化到磁盘。
每个ZooKeeper服务器都为客户端提供服务。客户端仅连接到一台服务器即可提交请求。读取请求从每个服务器数据库的本地副本提供服务。更改服务状态的请求(写请求)由协议协议处理。
作为协议协议的一部分,来自客户端的所有写请求都转发到称为领导者的单个服务器。其余的ZooKeeper服务器(称为跟随者)从领导者接收消息建议并同意消息传递。消息传递层负责替换失败者的领导者,并将跟随者与领导者同步。
ZooKeeper使用自定义的原子消息传递协议。由于消息传递层是原子层,因此ZooKeeper可以保证本地副本永远不会发散。领导者收到写请求时,它将计算要应用写操作时系统的状态,并将其转换为捕获此新状态的事务。
用途
ZooKeeper的编程接口刻意简单。但是,使用它,您可以实现更高阶的操作,例如同步原语,组成员身份,所有权等。
性能
ZooKeeper被设计为具有高性能。但是吗?Yahoo!的ZooKeeper开发团队的结果。研究表明确实如此。(请参见ZooKeeper吞吐量,随读/写比率的变化而定。)在读取数量超过写入数量的应用程序中,由于写入涉及同步所有服务器的状态,因此该性能特别高。(对于协调服务,通常情况下,读取数多于写入数。)
该ZooKeeper的吞吐量读写比变化是动物园管理员释放3.2的吞吐量图与双2GHz的至强和两个SATA 15K RPM驱动器的服务器上运行。一个驱动器用作专用的ZooKeeper日志设备。快照已写入OS驱动器。写请求是1K写,读是1K读。“服务器”指示ZooKeeper集合的大小,以及构成该服务的服务器的数量。大约还有30台其他服务器用于模拟客户端。ZooKeeper集成配置为使得领导者不允许来自客户端的连接。
注意
在3.2版中,与以前的3.1版相比,r / w性能提高了约2倍。
基准还表明它也是可靠的。存在错误的可靠性表明部署如何响应各种故障。图中标记的事件如下:
追随者的失败和恢复失败和其他追随者的恢复领导者的失败两个追随者的失败和恢复另一个领导者的失败
可靠性
为了显示随着故障注入系统随时间变化的行为,我们运行了由7台机器组成的ZooKeeper服务。我们使用与以前相同的饱和度基准,但是这次我们将写入百分比保持在恒定的30%,这是我们预期工作量的保守比率。
该图有一些重要的发现。首先,如果关注者失败并迅速恢复,则ZooKeeper能够在失败的情况下维持高吞吐量。但是,也许更重要的是,领导者选举算法允许系统恢复得足够快,以防止吞吐量大幅下降。根据我们的观察,ZooKeeper只需不到200毫秒即可选出新的领导者。第三,随着关注者的恢复,ZooKeeper能够在开始处理请求后再次提高吞吐量。
ZooKeeper项目
ZooKeeper已成功用于许多工业应用中。它用于Yahoo!作为Yahoo!的协调和故障恢复服务Message Broker是一个高度可扩展的发布-订阅系统,管理上千个主题以进行复制和数据传递。Yahoo!的提取服务使用它。搜寻器,它还管理故障恢复。一些雅虎!广告系统还使用ZooKeeper实施可靠的服务。
鼓励所有用户和开发人员加入社区并贡献他们的专业知识。有关更多信息,请参见Apache上的Zookeeper项目。
ZooKeeper入门指南
/doc/current/zookeeperStarted.html
入门:使用ZooKeeper协调分布式应用程序
本文档包含使您快速开始使用ZooKeeper的信息。它主要针对希望尝试的开发人员,并包含单个ZooKeeper服务器的简单安装说明,一些验证其正在运行的命令以及一个简单的编程示例。最后,为方便起见,有几节涉及更复杂的安装,例如,运行复制的部署以及优化事务日志。但是,有关商业部署的完整说明,请参阅《ZooKeeper管理员指南》。
先决条件
请参阅管理指南中的系统要求。
下载
要获得ZooKeeper发行版,请从Apache下载镜像之一下载最新的稳定版本。
独立运行
在独立模式下设置ZooKeeper服务器非常简单。服务器包含在单个JAR文件中,因此安装包括创建配置。
下载稳定的ZooKeeper版本后,将其解压缩并CD到根目录
要启动ZooKeeper,您需要一个配置文件。这是一个示例,在conf / zoo.cfg中创建它:
tickTime=2000dataDir=/var/lib/zookeeperclientPort=2181
该文件可以被命名为任何文件,但是为了便于讨论,将其命名为conf / zoo.cfg。更改dataDir的值以指定现有(空开头)目录。以下是每个字段的含义:
tickTime:ZooKeeper使用的基本时间单位(毫秒)。它用于做心跳,并且最小会话超时将是tickTime的两倍。
dataDir:存储内存数据库快照的位置,除非另有说明,否则存储数据库更新的事务日志。
clientPort:用于侦听客户端连接的端口
创建配置文件后,就可以启动ZooKeeper:
bin/zkServer.sh start
ZooKeeper使用log4j记录消息-程序员指南的“记录”部分中提供了更多详细信息。您将看到进入控制台的日志消息(默认)和/或一个日志文件,具体取决于log4j配置。
此处概述的步骤以独立模式运行ZooKeeper。没有复制,因此,如果ZooKeeper进程失败,该服务将关闭。这对于大多数开发情况都很好,但是要以复制方式运行ZooKeeper,请参阅“运行复制的ZooKeeper”。
管理ZooKeeper存储
对于长时间运行的生产系统,必须从外部管理ZooKeeper存储(dataDir和日志)。有关更多详细信息,请参见维护部分。
连接到ZooKeeper
$ bin/zkCli.sh -server 127.0.0.1:2181
这使您可以执行简单的类似文件的操作。
连接后,您应该会看到类似以下内容的信息:
Connecting to localhost:2181log4j:WARN No appenders could be found for logger (org.apache.zookeeper.ZooKeeper).log4j:WARN Please initialize the log4j system properly.Welcome to ZooKeeper!JLine support is enabled[zkshell: 0]
在shell中,键入help
以获取可以从客户端执行的命令的列表,如下所示:
[zkshell: 0] helpZooKeeper -server host:port cmd argsaddauth scheme authcloseconfig [-c] [-w] [-s]connect host:portcreate [-s] [-e] [-c] [-t ttl] path [data] [acl]delete [-v version] pathdeleteall pathdelquota [-n|-b] pathget [-s] [-w] pathgetAcl [-s] pathgetAllChildrenNumber pathgetEphemerals pathhistorylistquota pathls [-s] [-w] [-R] pathls2 path [watch]printwatches on|offquitreconfig [-s] [-v version] [[-file path] | [-members serverID=host:port1:port2;port3[,...]*]] | [-add serverId=host:port1:port2;port3[,...]]* [-remove serverId[,...]*]redo cmdnoremovewatches path [-c|-d|-a] [-l]rmr pathset [-s] [-v version] path datasetAcl [-s] [-v version] [-R] path aclsetquota -n|-b val pathstat [-w] pathsync path
从这里,您可以尝试一些简单的命令,以了解这种简单的命令行界面。首先,首先发出list命令,如中所示ls
,产生:
[zkshell: 8] ls /[zookeeper]
接下来,通过运行创建一个新的znodecreate /zk_test my_data
。这将创建一个新的znode并将字符串“ my_data”与该节点关联。您应该看到:
[zkshell: 9] create /zk_test my_dataCreated /zk_test
发出另一个ls /
命令以查看目录的外观:
[zkshell: 11] ls /[zookeeper, zk_test]
请注意,zk_test目录现已创建。
接下来,通过运行get
命令来验证数据是否与znode关联,如下所示:
[zkshell: 12] get /zk_testmy_datacZxid = 5ctime = Fri Jun 05 13:57:06 PDT mZxid = 5mtime = Fri Jun 05 13:57:06 PDT pZxid = 5cversion = 0dataVersion = 0aclVersion = 0ephemeralOwner = 0dataLength = 7numChildren = 0
我们可以通过发出set
命令来更改与zk_test相关的数据,如下所示:
[zkshell: 14] set /zk_test junkcZxid = 5ctime = Fri Jun 05 13:57:06 PDT mZxid = 6mtime = Fri Jun 05 14:01:52 PDT pZxid = 5cversion = 0dataVersion = 1aclVersion = 0ephemeralOwner = 0dataLength = 4numChildren = 0[zkshell: 15] get /zk_testjunkcZxid = 5ctime = Fri Jun 05 13:57:06 PDT mZxid = 6mtime = Fri Jun 05 14:01:52 PDT pZxid = 5cversion = 0dataVersion = 1aclVersion = 0ephemeralOwner = 0dataLength = 4numChildren = 0
(请注意,我们get
在设置数据后做了一个,确实确实发生了变化。
最后,delete
通过发出以下命令来创建节点:
[zkshell: 16] delete /zk_test[zkshell: 17] ls /[zookeeper][zkshell: 18]
现在就这样。要了解更多信息,请参见Zookeeper CLI。
编程到ZooKeeper
ZooKeeper具有Java绑定和C绑定。它们在功能上是等效的。C绑定存在两种变体:单线程和多线程。这些区别仅在于消息传递循环的完成方式。有关更多信息,请参见《ZooKeeper程序员指南》中的“编程示例”,以获取使用不同API的示例代码。
运行复制的ZooKeeper
以独立模式运行ZooKeeper便于评估,某些开发和测试。但是在生产中,您应该在复制模式下运行ZooKeeper。同一应用程序中的一组服务器的复制组称为仲裁,并且在复制模式下,仲裁中的所有服务器都具有相同配置文件的副本。
注意
对于复制模式,至少需要三个服务器,并且强烈建议您使用奇数个服务器。如果只有两台服务器,那么您将处于其中其中一台出现故障的情况,那就是没有足够的计算机来构成多数仲裁。由于存在两个单点故障,因此两个服务器本来就不如单个服务器稳定。
复制模式所需的conf / zoo.cfg文件类似于独立模式下使用的文件,但有一些区别。这是一个例子:
tickTime=2000dataDir=/var/lib/zookeeperclientPort=2181initLimit=5syncLimit=2server.1=zoo1:2888:3888server.2=zoo2:2888:3888server.3=zoo3:2888:3888
新条目initLimit是超时ZooKeeper用于限制仲裁中的ZooKeeper服务器必须连接到领导者的时间长度。条目syncLimit限制服务器距领导者可以过时的时间。
对于这两个超时,您都可以使用tickTime指定时间单位。在此示例中,initLimit的超时是5个滴答声,即2000毫秒一个滴答声,即10秒。
表格server.X的条目列出了组成ZooKeeper服务的服务器。服务器启动时,它通过在数据目录中查找文件myid来知道它是哪台服务器。该文件包含ASCII的服务器号。
最后,记下每个服务器名称后的两个端口号:“ 2888”和“ 3888”。对等方使用前一个端口连接到其他对等方。这种连接是必需的,以便对等方可以进行通信,例如,以商定更新顺序。更具体地说,ZooKeeper服务器使用此端口将关注者连接到领导者。当出现新的领导者时,跟随者使用此端口打开与领导者的TCP连接。因为默认的领导者选举也使用TCP,所以我们当前需要另一个端口来进行领导者选举。这是服务器条目中的第二个端口。
注意
如果要在单台计算机上测试多个服务器,请为每个服务器指定服务器名称为localhost,具有唯一的仲裁和领导者选择端口(例如,在上面的示例中为2888:3888、2889:3889、2890:3890)。配置文件。当然,也需要单独的_dataDir_s和不同的_clientPort_s(在上面的复制示例中,在单个localhost上运行,您仍然会有三个配置文件)。
请注意,在一台计算机上设置多个服务器不会产生任何冗余。如果发生某些事情导致机器死机,则所有zookeeper服务器都将处于脱机状态。完全冗余要求每个服务器都有自己的计算机。它必须是完全独立的物理服务器。同一物理主机上的多个虚拟机仍然容易受到该主机完全故障的影响。
如果ZooKeeper机器中有多个网络接口,还可以指示ZooKeeper绑定所有接口,并在网络出现故障时自动切换到正常接口。有关详细信息,请参阅“配置参数”。
其他优化
还有几个其他配置参数可以大大提高性能:
为了获得较低的更新延迟,拥有专用的事务日志目录非常重要。默认情况下,事务日志与数据快照和myid文件放在同一目录中。dataLogDir参数指示用于事务日志的其他目录。
发行说明-ZooKeeper
/doc/current/releasenotes.html
ZOOKEEPER-3112-由于连接时出现UnresolvedAddressException而导致fd泄漏。ZOOKEEPER-3215-处理Java 9/11向java.nio.ByteBuffer方法添加的协变量返回类型ZOOKEEPER-3772-JettyAdminServer不应允许HTTP TRACE方法ZOOKEEPER-3792-在3.5.7和3.6.0中协调文档站点ZOOKEEPER-3801-修复pom中的Jenkins链接ZOOKEEPER-3814-即使禁用了动态重新配置,ZooKeeper的配置也会传播ZOOKEEPER-3818-修复zkServer.sh status命令以支持仅SSL服务器ZOOKEEPER-3829-节点扩展后Zookeeper拒绝请求ZOOKEEPER-3830-添加新节点后,如果此新节点为领导者,则Zookeeper集群不会提交任何建议ZOOKEEPER-3832-ZKHostnameVerifier拒绝带有subjectAltNames的有效证书ZOOKEEPER-3842-Zookeeper群集的向上扩展不适用于reconfigEnabled = falseZOOKEEPER-3857-提交了Curator测试后无法构建ZooKeeper 3.6ZOOKEEPER-3865-修复ZooKeeperServer构造函数的向后兼容性ZOOKEEPER-3876-配置IPV6时zkServer.sh status命令失败ZOOKEEPER-3878-如果IPV6未包含在方括号中,则客户端连接失败ZOOKEEPER-3885-zoo_aremove_watches segfault:zk_hashtable需要锁定!ZOOKEEPER-3895-空Multi操作时客户端NullPointerExceptionZOOKEEPER-3905-竞争条件导致即使客户端的证书身份验证失败,也会为客户端创建会话