ZooKeeper 管理员指南
部署和管理指南
- 部署
- 管理
部署
本节包含有关部署 ZooKeeper 的信息,涵盖以下主题
前两节假设您有兴趣在生产环境(例如数据中心)中安装 ZooKeeper。最后一节涵盖了您在有限范围内设置 ZooKeeper 的情况 - 用于评估、测试或开发 - 但不是在生产环境中。
系统要求
支持的平台
ZooKeeper 由多个组件组成。某些组件得到广泛支持,而其他组件仅在较小的平台集上受支持。
- 客户端 是 Java 客户端库,应用程序使用它连接到 ZooKeeper 集群。
- 服务器 是运行在 ZooKeeper 集群节点上的 Java 服务器。
- 原生客户端 是一个用 C 实现的客户端,类似于 Java 客户端,应用程序使用它连接到 ZooKeeper 集群。
- Contrib 指的是多个可选的附加组件。
以下矩阵描述了在不同操作系统平台上运行每个组件的支持级别。
支持矩阵
操作系统 | 客户端 | 服务器 | 原生客户端 | Contrib |
---|---|---|---|---|
GNU/Linux | 开发和生产 | 开发和生产 | 开发和生产 | 开发和生产 |
Solaris | 开发和生产 | 开发和生产 | 不支持 | 不支持 |
FreeBSD | 开发和生产 | 开发和生产 | 不支持 | 不支持 |
Windows | 开发和生产 | 开发和生产 | 不支持 | 不支持 |
Mac OS X | 仅支持开发 | 仅支持开发 | 不支持 | 不支持 |
对于矩阵中未明确提及支持的任何操作系统,组件可能工作,也可能不工作。ZooKeeper 社区会修复报告的其他平台上的明显错误,但没有完全的支持。
所需软件
ZooKeeper 运行在 Java 1.8 或更高版本(支持 JDK 8 LTS、JDK 11 LTS、JDK 12,不支持 Java 9 和 10)上。它作为 ZooKeeper 服务器的 集群(ensemble) 运行。一个集群建议的最小规模是三台 ZooKeeper 服务器,我们也建议它们运行在不同的机器上。在 Yahoo!,ZooKeeper 通常部署在专用的 RHEL 服务器上,配备双核处理器、2GB 内存和 80GB IDE 硬盘。
集群(多服务器)安装设置
为了获得可靠的 ZooKeeper 服务,您应该将 ZooKeeper 部署在称为 集群(ensemble) 的环境中。只要集群中的大多数服务器正常运行,服务就可用。由于 ZooKeeper 需要多数派,最好使用奇数台机器。例如,使用四台机器时,ZooKeeper 只能容忍一台机器的故障;如果两台机器发生故障,剩下的两台机器不构成多数派。然而,使用五台机器时,ZooKeeper 可以容忍两台机器的故障。
注意
如 ZooKeeper 入门指南 中所述,容错集群安装至少需要三台服务器,强烈建议您使用奇数台服务器。
通常三台服务器对于生产环境安装来说已经足够了,但为了在维护期间获得最高可靠性,您可能希望安装五台服务器。使用三台服务器时,如果您对其中一台进行维护,则在该维护期间很容易受到其他两台服务器中一台发生故障的影响。如果您有五台服务器正在运行,您可以停掉一台进行维护,并且知道即使其他四台中的一台突然出现故障,您也仍然没问题。
您的冗余考虑应该包括环境的所有方面。如果您有三台 ZooKeeper 服务器,但它们的网线都插入同一个网络交换机,那么该交换机的故障将导致整个集群瘫痪。
以下是设置集群中一个服务器的步骤。这些步骤应在集群中的每个主机上执行。
-
安装 Java JDK。您可以使用系统的原生包管理系统,或从以下地址下载 JDK:http://java.sun.com/javase/downloads/index.jsp
-
设置 Java 堆大小(heap size)。这一点非常重要,可以避免发生交换(swapping),交换会严重降低 ZooKeeper 的性能。要确定正确的值,请使用负载测试,并确保您远低于导致交换的使用限制。保守一些 - 对于 4GB 内存的机器,使用最大堆大小为 3GB。
-
安装 ZooKeeper 服务器软件包。可以从以下地址下载:https://zookeeper.net.cn/releases.html
-
创建一个配置文件。此文件可以命名为任何名称。使用以下设置作为起点:
tickTime=2000 dataDir=/var/lib/zookeeper/ clientPort=2181 initLimit=5 syncLimit=2 server.1=zoo1:2888:3888 server.2=zoo2:2888:3888 server.3=zoo3:2888:3888
您可以在 配置参数 一节中找到这些及其他配置设置的含义。这里提一些注意事项:作为 ZooKeeper 集群一部分的每台机器都应该知道集群中的所有其他机器。您可以通过一系列形式为 server.id=host:port:port 的行来实现这一点。(参数 host 和 port 很直接,对于每台服务器,您需要先指定一个 Quorum 端口,然后指定一个用于 ZooKeeper 领导者选举的专用端口)。从 ZooKeeper 3.6.0 开始,您还可以为每个 ZooKeeper 服务器实例 指定多个地址(当集群中可以使用多个物理网络接口时,这可以提高可用性)。您通过创建一个名为 myid 的文件,为每台服务器指定一个服务器 ID,该文件位于该服务器的数据目录中,如配置文件参数 dataDir 所指定。
-
myid 文件只包含该机器 ID 的一行文本,仅此而已。因此,服务器 1 的 myid 文件将只包含文本 "1",没有其他内容。该 ID 在集群内必须是唯一的,且值应在 1 到 255 之间。重要: 如果启用扩展功能,例如 TTL 节点(见下文),由于内部限制,ID 必须在 1 到 254 之间。
-
在与 myid 文件相同的目录中创建一个初始化标记文件 initialize。此文件表示预期数据目录是空的。当此文件存在时,将创建一个空数据库并删除标记文件。当此文件不存在时,空的数据目录意味着该对等体将没有投票权,并且在与活动领导者通信之前不会填充数据目录。此文件的预期用途是仅在启动新的集群时创建它。
-
如果您的配置文件已设置好,您可以启动 ZooKeeper 服务器
$ java -cp zookeeper.jar:lib/*:conf org.apache.zookeeper.server.quorum.QuorumPeerMain zoo.conf
QuorumPeerMain 启动 ZooKeeper 服务器,同时也会注册 JMX 管理 MBean,这允许通过 JMX 管理控制台进行管理。ZooKeeper JMX 文档 中包含了使用 JMX 管理 ZooKeeper 的详细信息。请参阅发行版中包含的脚本 bin/zkServer.sh,以获取启动服务器实例的示例。8. 通过连接到主机来测试您的部署:在 Java 中,您可以运行以下命令来执行简单操作:
$ bin/zkCli.sh -server 127.0.0.1:2181
单服务器和开发者安装设置
如果您想为开发目的设置 ZooKeeper,您可能希望设置一个 ZooKeeper 的单服务器实例,然后在您的开发机器上安装 Java 或 C 客户端库及绑定。
设置单服务器实例的步骤与上述类似,只是配置文件更简单。您可以在 ZooKeeper 入门指南 的 在单服务器模式下安装和运行 ZooKeeper 一节中找到完整的说明。
有关安装客户端库的信息,请参考 ZooKeeper 程序员指南 的 绑定 一节。
管理
本节包含有关运行和维护 ZooKeeper 的信息,涵盖以下主题
- 设计 ZooKeeper 部署方案
- 准备工作
- 注意事项:ZooKeeper 的优势和局限性
- 管理
- 维护
- 进程守护
- 监控
- 日志
- 故障排除
- 配置参数
- ZooKeeper 命令
- 数据文件管理
- 应避免的事项
- 最佳实践
设计 ZooKeeper 部署方案
ZooKeeper 的可靠性基于两个基本假设。
- 部署中只有少数服务器会发生故障。这里的 故障(Failure) 指机器崩溃,或网络中将服务器与多数派隔离开来的错误。
- 部署的机器正常运行。正常运行意味着正确执行代码、时钟正常工作以及存储和网络组件性能稳定。
以下各节包含供 ZooKeeper 管理员参考的注意事项,以最大化这些假设成立的可能性。其中一些是跨机器考虑因素,另一些是您在部署中每台机器上都应该考虑的事项。
跨机器要求
为了使 ZooKeeper 服务处于活动状态,必须有大多数未发生故障且能够相互通信的机器。对于一个包含 N 个服务器的 ZooKeeper 集群,如果 N 是奇数,集群可以容忍高达 N/2 台服务器的故障而不会丢失任何 znode 数据;如果 N 是偶数,集群可以容忍高达 N/2-1 台服务器的故障。
例如,如果我们有一个包含 3 台服务器的 ZooKeeper 集群,它能够容忍高达 1 (3/2) 台服务器的故障。如果我们有一个包含 5 台服务器的 ZooKeeper 集群,它能够容忍高达 2 (5/2) 台服务器的故障。如果 ZooKeeper 集群有 6 台服务器,它也能容忍高达 2 (6/2-1) 台服务器的故障而不会丢失数据,并防止“脑裂”问题。
ZooKeeper 集群通常拥有奇数台服务器。这是因为对于偶数台服务器,容错能力与少一台服务器的集群相同(5 节点集群和 6 节点集群都容忍 2 台故障),但集群必须为多一台服务器维护额外的连接和数据传输。
为了实现容忍故障的最高可能性,您应该努力使机器故障相互独立。例如,如果大多数机器共享同一个交换机,那么该交换机的故障可能导致关联故障并使服务瘫痪。共享电源电路、冷却系统等也是如此。
单机器要求
如果 ZooKeeper 必须与其他应用程序争用存储介质、CPU、网络或内存等资源,其性能将显著下降。ZooKeeper 提供强大的持久性保证(durability guarantees),这意味着它在允许负责更改的操作完成之前,会使用存储介质记录更改日志。因此,您应该意识到这种依赖性,如果您想确保 ZooKeeper 操作不会被您的存储介质拖慢,请务必非常小心。以下是一些您可以采取的措施来最大程度地减少此类性能下降:
- ZooKeeper 的事务日志必须位于专用设备上。(专用分区是不够的。)ZooKeeper 按顺序写入日志,没有寻址。与其他进程共享您的日志设备可能会导致寻址和争用,进而导致多秒延迟。
- 不要将 ZooKeeper 置于可能导致交换(swap)的情况。为了使 ZooKeeper 能够及时运行,绝对不能允许它发生交换。因此,请确保分配给 ZooKeeper 的最大堆大小不超过 ZooKeeper 可用的实际内存量。有关更多信息,请参阅下文的 应避免的事项。
准备工作
注意事项:ZooKeeper 的优势和局限性
管理
维护
ZooKeeper 集群需要进行的长期维护很少,但是您必须了解以下事项:
持续的数据目录清理
ZooKeeper 的 数据目录 包含特定服务集群存储的 znodes 的持久副本文件。这些是快照文件和事务日志文件。当对 znodes 进行更改时,这些更改会被附加到事务日志中。有时,当日志文件变得很大时,会将所有 znodes 当前状态的快照写入文件系统,并为未来的事务创建一个新的事务日志文件。在生成快照期间,ZooKeeper 可能会继续将传入的事务附加到旧的日志文件中。因此,一些比快照新的事务可能会在紧接快照之前的最后一个事务日志中找到。
在使用默认配置时(参见下面的 autopurge),ZooKeeper 服务器不会删除旧的快照和日志文件,这是运维人员的责任。每个服务环境都不同,因此管理这些文件的要求可能因安装而异(例如备份)。
PurgeTxnLog 工具实现了管理员可以使用的简单保留策略。 API 文档 包含了调用约定(参数等)的详细信息。
在以下示例中,保留了最后 count 个快照及其对应的日志,其余的都被删除。此值的
java -cp zookeeper.jar:lib/slf4j-api-1.7.30.jar:lib/logback-classic-1.2.10.jar:lib/logback-core-1.2.10.jar:conf org.apache.zookeeper.server.PurgeTxnLog <dataDir> <snapDir> -n <count>
快照和相应事务日志的自动清除功能是在 3.4.0 版本中引入的,可以通过以下配置参数启用:autopurge.snapRetainCount 和 autopurge.purgeInterval。有关更多信息,请参阅下文的 高级配置。
调试日志清理 (logback)
请参阅本文档中关于 日志 的部分。预计您将使用内置的 logback 功能设置一个滚动文件附加器(rolling file appender)。发行版 tar 包的 conf/logback.xml
中的示例配置文件提供了这方面的示例。
进程守护
您会希望有一个监督进程来管理您的每个 ZooKeeper 服务器进程(JVM)。ZK 服务器被设计为“快速失败(fail fast)”,这意味着如果在发生无法恢复的错误时,它将关闭(进程退出)。由于 ZooKeeper 服务集群是高度可靠的,这意味着即使某个服务器可能宕机,整个集群仍然处于活动状态并处理请求。此外,由于集群具有“自愈(self healing)”能力,发生故障的服务器在重新启动后将自动重新加入集群,无需任何手动干预。
拥有一个监督进程,例如 daemontools 或 SMF(也有其他监督进程选项可用,使用哪一个取决于您,这些只是两个示例)来管理您的 ZooKeeper 服务器,可以确保如果进程异常退出,它将自动重新启动并快速重新加入集群。
此外,还建议配置 ZooKeeper 服务器进程,使其在发生 OutOfMemoryError** 时终止并转储(dump)其堆内存。这可以通过在 Linux 和 Windows 上分别使用以下参数启动 JVM 来实现。ZooKeeper 附带的 zkServer.sh 和 zkServer.cmd 脚本设置了这些选项。
-XX:+HeapDumpOnOutOfMemoryError -XX:OnOutOfMemoryError='kill -9 %p'
"-XX:+HeapDumpOnOutOfMemoryError" "-XX:OnOutOfMemoryError=cmd /c taskkill /pid %%%%p /t /f"
监控
ZooKeeper 服务可以通过以下三种主要方式之一进行监控:
- 通过使用 四字命令 的方式连接命令端口
- 使用 JMX
- 使用
zkServer.sh status
命令
日志
ZooKeeper 使用 SLF4J 1.7 版本作为其日志记录基础设施。默认情况下,ZooKeeper 附带 LOGBack 作为日志记录后端,但您也可以使用任何其他受支持的日志记录框架。
ZooKeeper 默认的 logback.xml 文件位于 conf 目录中。Logback 要求 logback.xml 位于工作目录(ZooKeeper 运行所在的目录)或可从类路径(classpath)访问。
有关 SLF4J 的更多信息,请参阅 其手册。
有关 Logback 的更多信息,请参阅 Logback 网站。
故障排除
- 服务器因文件损坏无法启动 :服务器可能无法读取其数据库并因此无法启动,这是由于 ZooKeeper 服务器事务日志中的某些文件损坏所致。在加载 ZooKeeper 数据库时,您会看到一些 IOException。在这种情况下,请确保集群中的所有其他服务器都已启动并正常工作。在命令端口上使用 "stat" 命令查看它们是否处于良好状态。在确认集群中的所有其他服务器都已启动后,您可以继续清理损坏服务器的数据库。删除 datadir/version-2 和 datalogdir/version-2/ 中的所有文件。然后重新启动服务器。
配置参数
ZooKeeper 的行为由 ZooKeeper 配置文件控制。此文件设计为,假设磁盘布局相同,集群中的所有服务器都可以使用完全相同的文件。如果服务器使用不同的配置文件,则必须谨慎确保所有不同配置文件中的服务器列表匹配。
注意
在 3.5.0 及更高版本中,其中一些参数应放置在动态配置文件中。如果它们被放置在静态配置文件中,ZooKeeper 将自动将其移动到动态配置文件中。有关更多信息,请参阅 动态重新配置。
基本配置
以下是必须在配置文件中定义的基本配置关键字:
-
clientPort :监听客户端连接的端口;即客户端尝试连接的端口。
-
secureClientPort :监听使用 SSL 的安全客户端连接的端口。clientPort 指定明文连接的端口,而 secureClientPort 指定 SSL 连接的端口。同时指定两者将启用混合模式,省略任一则会禁用该模式。注意,当用户将 zookeeper.serverCnxnFactory、zookeeper.clientCnxnSocket 配置为 Netty 时,SSL 功能才会启用。
-
observerMasterPort :监听观察者连接的端口;即观察者尝试连接的端口。如果设置了此属性,服务器在 follower 模式下以及 leader 模式下都会托管观察者连接,并且在 observer 模式下会相应地尝试连接到任何投票对等体。
-
dataDir :ZooKeeper 存储内存数据库快照(in-memory database snapshots),以及(除非另有指定)数据库更新的事务日志的位置。
注意
注意事务日志的存放位置。专用事务日志设备是持续良好性能的关键。将日志放在繁忙的设备上会严重影响性能。
- tickTime :单个 tick 的时长,它是 ZooKeeper 使用的基本时间单位,以毫秒为单位衡量。它用于规范心跳(heartbeats)和超时(timeouts)。例如,最小会话超时将是两个 tick。
高级配置
本节中的配置设置是可选的。您可以使用它们进一步微调(fine tune)ZooKeeper 服务器的行为。有些还可以使用 Java 系统属性(system properties)设置,通常形式为 zookeeper.keyword。如果可用,具体的系统属性将在下方注明。
- dataLogDir :(无 Java 系统属性)此选项将指示机器将事务日志写入 dataLogDir,而不是 dataDir。这允许使用专用的日志设备,并有助于避免日志记录和快照之间的竞争。
注意
拥有专用日志设备对吞吐量和稳定延迟有很大影响。强烈建议专门使用一个日志设备,并将 dataLogDir 设置为指向该设备上的目录,然后确保将 dataDir 指向不位于该设备上的目录。
- globalOutstandingLimit :(Java 系统属性:zookeeper.globalOutstandingLimit.)客户端提交请求的速度可能比 ZooKeeper 处理它们的速度快,尤其是在客户端数量很多的情况下。为了防止 ZooKeeper 因排队的请求而耗尽内存,ZooKeeper 将对客户端进行限流(throttle),使得整个集群中未完成的请求总数不超过 globalOutstandingLimit,这些限额在成员之间平均分配。默认限制为 1,000,例如,对于 3 个成员的集群,每个成员的单独限制将为 1000 / 2 = 500。
-
preAllocSize :(Java 系统属性:zookeeper.preAllocSize)为了避免寻址,ZooKeeper 在事务日志文件中以 preAllocSize 千字节的块大小预分配(pre-allocate)空间。默认块大小为 64M。更改块大小的一个原因是如果在快照更频繁时减小块大小。(另请参阅 snapCount 和 snapSizeLimitInKb)。
-
snapCount :(Java 系统属性:zookeeper.snapCount)ZooKeeper 使用快照和事务日志(可以理解为 write-ahead log)记录其事务。在生成快照(并滚动事务日志)之前,事务日志中记录的事务数量由 snapCount 决定。为了防止 Quorum 中的所有机器同时生成快照,每个 ZooKeeper 服务器将在事务日志中的事务数量达到 [snapCount/2+1, snapCount] 范围内运行时生成的随机值时生成快照。默认的 snapCount 是 100,000。
-
commitLogCount * :(Java 系统属性:zookeeper.commitLogCount)ZooKeeper 维护一个内存中的已提交请求列表,以便在 followers 落后不多时快速与其同步。这提高了在快照较大(>100,000)情况下的同步性能。默认值为 500,这是建议的最小值。
-
snapSizeLimitInKb :(Java 系统属性:zookeeper.snapSizeLimitInKb)ZooKeeper 使用快照和事务日志(可以理解为 write-ahead log)记录其事务。在生成快照(并滚动事务日志)之前,事务日志中记录的事务集合允许的总大小(以字节为单位)由 snapSize 决定。为了防止 Quorum 中的所有机器同时生成快照,每个 ZooKeeper 服务器将在事务日志中的事务集合大小(以字节为单位)达到 [snapSize/2+1, snapSize] 范围内运行时生成的随机值时生成快照。每个文件系统都有一个最小标准文件大小,为了使此功能有效运行,选择的值必须大于该值。默认的 snapSizeLimitInKb 是 4,194,304 (4GB)。非正值将禁用此功能。
-
txnLogSizeLimitInKb :(Java 系统属性:zookeeper.txnLogSizeLimitInKb)ZooKeeper 事务日志文件也可以使用 txnLogSizeLimitInKb 更直接地控制。较大的事务日志在使用事务日志进行同步时可能导致 follower 同步变慢。这是因为 leader 必须扫描磁盘上相应的日志文件以找到开始同步的事务。默认情况下,此功能是关闭的,snapCount 和 snapSizeLimitInKb 是唯一限制事务日志大小的值。启用后,当达到任何限制时,ZooKeeper 将滚动日志。请注意,实际日志大小可能会超出此值,超出的部分是序列化事务的大小。另一方面,如果此值设置得太接近(或小于) preAllocSize,可能导致 ZooKeeper 对每个事务都滚动日志。虽然这不是正确性问题,但这可能导致性能严重下降。为了避免这种情况并充分利用此功能,建议将该值设置为 N * preAllocSize,其中 N >= 2。
-
maxCnxns :(Java 系统属性:zookeeper.maxCnxns)限制可连接到 ZooKeeper 服务器(每个服务器的每个客户端端口)的并发连接总数。这用于防止某些类型的 DoS 攻击。默认值为 0,将其设置为 0 将完全取消对并发连接总数的限制。对 serverCnxnFactory 和 secureServerCnxnFactory 的连接数是单独计算的,因此一个对等体被允许托管高达 2*maxCnxns 的连接,前提是它们的类型是适当的。
-
maxClientCnxns :(无 Java 系统属性)限制单个客户端(通过 IP 地址标识)可以连接到 ZooKeeper 集群中单个成员的并发连接数(在套接字级别)。这用于防止某些类型的 DoS 攻击,包括文件描述符耗尽。默认值为 60。将其设置为 0 将完全取消对并发连接的限制。
-
clientPortAddress :3.3.0 版本新增: 监听客户端连接的地址(ipv4、ipv6 或主机名);即客户端尝试连接的地址。这是可选的,默认情况下我们绑定端口的方式使得服务器上任何地址/接口/网卡上连接到 clientPort 的任何连接都将被接受。
-
minSessionTimeout :(无 Java 系统属性)3.3.0 版本新增: 服务器允许客户端协商的最小会话超时时间(以毫秒为单位)。默认值为 tickTime 的 2 倍。
-
maxSessionTimeout :(无 Java 系统属性)3.3.0 版本新增: 服务器允许客户端协商的最大会话超时时间(以毫秒为单位)。默认值为 tickTime 的 20 倍。
-
fsync.warningthresholdms :(Java 系统属性:zookeeper.fsync.warningthresholdms)3.3.4 版本新增: 当事务日志(WAL)中的 fsync 操作耗时超过此值时,日志中将输出一条警告消息。该值以毫秒为单位指定,默认值为 1000。此值只能设置为系统属性。
-
maxResponseCacheSize :(Java 系统属性:zookeeper.maxResponseCacheSize)当设置为正整数时,它决定了缓存的大小,该缓存存储最近读取记录的序列化形式。有助于节省热门 znode 的序列化成本。可以使用指标 response_packet_cache_hits 和 response_packet_cache_misses 来针对给定工作负载调整此值。该功能默认开启,值为 400,设置为 0 或负整数则关闭该功能。
-
maxGetChildrenResponseCacheSize :(Java 系统属性:zookeeper.maxGetChildrenResponseCacheSize)3.6.0 版本新增: 类似于 maxResponseCacheSize,但应用于 get children 请求。可以使用指标 response_packet_get_children_cache_hits 和 response_packet_get_children_cache_misses 来针对给定工作负载调整此值。该功能默认开启,值为 400,设置为 0 或负整数则关闭该功能。
-
autopurge.snapRetainCount :(无 Java 系统属性)3.4.0 版本新增: 启用后,ZooKeeper 自动清除功能会在 dataDir 和 dataLogDir 中分别保留 autopurge.snapRetainCount 最新快照和相应的事务日志,并删除其余的。默认值为 3。最小值为 3。
-
autopurge.purgeInterval :(无 Java 系统属性)3.4.0 版本新增: 触发清除任务的时间间隔,以小时为单位。设置为正整数(1 及以上)以启用自动清除。默认值为 0。
-
syncEnabled :(Java 系统属性:zookeeper.observer.syncEnabled)3.4.6, 3.5.0 版本新增: 观察者现在默认像参与者一样记录事务并将快照写入磁盘。这减少了观察者在重新启动时的恢复时间。设置为 "false" 禁用此功能。默认值为 "true"。
-
extendedTypesEnabled :(仅限 Java 系统属性:zookeeper.extendedTypesEnabled)3.5.4, 3.6.0 版本新增: 设置为
true
以启用扩展功能,例如创建 TTL 节点。默认情况下它们是禁用的。重要:启用后,由于内部限制,服务器 ID 必须小于 255。 -
emulate353TTLNodes :(仅限 Java 系统属性:zookeeper.emulate353TTLNodes)。3.5.4, 3.6.0 版本新增: 由于 [ZOOKEEPER-2901] (https://issues.apache.org/jira/browse/ZOOKEEPER-2901) 的原因,在 3.5.3 版本中创建的 TTL 节点在 3.5.4/3.6.0 中不受支持。但是,可以通过 zookeeper.emulate353TTLNodes 系统属性提供一个变通方法(workaround)。如果您在 ZooKeeper 3.5.3 中使用了 TTL 节点并需要保持兼容性,除了设置 zookeeper.extendedTypesEnabled 外,还要将 zookeeper.emulate353TTLNodes 设置为
true
。注意:由于该 bug,服务器 ID 必须小于或等于 127。此外,支持的最大 TTL 值是1099511627775
,小于 3.5.3 中允许的值 (1152921504606846975
)。 -
watchManagerName :(仅限 Java 系统属性:zookeeper.watchManagerName)3.6.0 版本新增: 在 ZOOKEEPER-1179 中添加。新的 watcher 管理器 WatchManagerOptimized,以优化在高负载 watcher 使用案例中的内存开销。此配置用于定义要使用的 watcher 管理器。目前,我们只支持 WatchManager 和 WatchManagerOptimized。
-
watcherCleanThreadsNum :(仅限 Java 系统属性:zookeeper.watcherCleanThreadsNum)3.6.0 版本新增: 在 ZOOKEEPER-1179 中添加。新的 watcher 管理器 WatchManagerOptimized 将延迟清理(lazily clean up)死亡的 watcher,此配置用于决定 WatcherCleaner 中使用的线程数量。更多线程通常意味着更大的清理吞吐量。默认值为 2,即使在高负载和持续的会话关闭/重新创建情况下也足够好用。
-
watcherCleanThreshold :(仅限 Java 系统属性:zookeeper.watcherCleanThreshold)3.6.0 版本新增: 在 ZOOKEEPER-1179 中添加。新的 watcher 管理器 WatchManagerOptimized 将延迟清理死亡的 watcher,清理过程相对较重,批量处理可以降低成本并提高性能。此设置用于决定批量大小(batch size)。默认值为 1000,如果没有内存或清理速度问题,则无需更改。
-
watcherCleanIntervalInSeconds :(仅限 Java 系统属性:zookeeper.watcherCleanIntervalInSeconds)3.6.0 版本新增: 在 ZOOKEEPER-1179 中添加。新的 watcher 管理器 WatchManagerOptimized 将延迟清理死亡的 watcher,清理过程相对较重,批量处理可以降低成本并提高性能。除了 watcherCleanThreshold 外,此设置用于在一定时间后清理死亡的 watcher,即使死亡 watcher 的数量没有达到 watcherCleanThreshold,这样我们就不会让死亡 watcher 在那里停留太长时间。默认设置为 10 分钟,通常无需更改。
-
maxInProcessingDeadWatchers :(仅限 Java 系统属性:zookeeper.maxInProcessingDeadWatchers)3.6.0 版本新增: 在 ZOOKEEPER-1179 中添加。此设置用于控制 WatcherCleaner 中的积压量(backlog),当达到此数量时,会减慢向 WatcherCleaner 添加死亡 watcher 的速度,进而减慢添加和关闭 watcher 的速度,从而避免 OOM(内存溢出)问题。默认情况下没有限制,您可以将其设置为 watcherCleanThreshold * 1000 之类的值。
-
bitHashCacheSize :(仅限 Java 系统属性:zookeeper.bitHashCacheSize)3.6.0 版本新增:在 ZOOKEEPER-1179 中添加。此设置用于决定 BitHashSet 实现中 HashSet 缓存的大小。如果没有 HashSet,我们需要使用 O(N) 的时间来获取元素,其中 N 是 elementBits 中的位数。但是我们需要保持大小较小,以确保它不会占用太多内存,这是内存和时间复杂度之间的权衡。默认值为 10,这似乎是一个相对合理的缓存大小。
-
fastleader.minNotificationInterval :(Java 系统属性:zookeeper.fastleader.minNotificationInterval)领导者选举中两次连续通知检查之间的时间长度下限。此间隔决定了对等体等待多长时间来检查选举票数集合,并影响选举解决的速度。对于长时间的选举,此间隔遵循配置的最小(此参数)和配置的最大(fastleader.maxNotificationInterval)之间的退避策略(backoff strategy)。
-
fastleader.maxNotificationInterval : (Java 系统属性: zookeeper.fastleader.maxNotificationInterval) Leader 选举中两次连续通知检查之间的时间长度上限。此间隔决定了对等节点等待检查选举投票集合的时间,并影响选举解决的速度。对于长时间的选举,该间隔遵循从配置的最小值 (fastleader.minNotificationInterval) 到配置的最大值(此参数)的退避策略。
-
connectionMaxTokens : (Java 系统属性: zookeeper.connection_throttle_tokens) 3.6.0 版本新增: 这是用于调整服务器端连接限流器(一种基于令牌、可选概率丢弃的限速机制)的参数之一。此参数定义了令牌桶中的最大令牌数量。设置为 0 时,限流被禁用。默认值是 0。
-
connectionTokenFillTime : (Java 系统属性: zookeeper.connection_throttle_fill_time) 3.6.0 版本新增: 这是用于调整服务器端连接限流器(一种基于令牌、可选概率丢弃的限速机制)的参数之一。此参数定义了以毫秒为单位的时间间隔,在此间隔内,令牌桶会被重新填充 connectionTokenFillCount 个令牌。默认值是 1。
-
connectionTokenFillCount : (Java 系统属性: zookeeper.connection_throttle_fill_count) 3.6.0 版本新增: 这是用于调整服务器端连接限流器(一种基于令牌、可选概率丢弃的限速机制)的参数之一。此参数定义了每隔 connectionTokenFillTime 毫秒要添加到令牌桶中的令牌数量。默认值是 1。
-
connectionFreezeTime : (Java 系统属性: zookeeper.connection_throttle_freeze_time) 3.6.0 版本新增: 这是用于调整服务器端连接限流器(一种基于令牌、可选概率丢弃的限速机制)的参数之一。此参数定义了以毫秒为单位的时间间隔,在此间隔内会调整丢弃概率。设置为 -1 时,概率丢弃被禁用。默认值是 -1。
-
connectionDropIncrease : (Java 系统属性: zookeeper.connection_throttle_drop_increase) 3.6.0 版本新增: 这是用于调整服务器端连接限流器(一种基于令牌、可选概率丢弃的限速机制)的参数之一。此参数定义了要增加的丢弃概率。限流器每隔 connectionFreezeTime 毫秒检查一次,如果令牌桶为空,丢弃概率将增加 connectionDropIncrease。默认值是 0.02。
-
connectionDropDecrease : (Java 系统属性: zookeeper.connection_throttle_drop_decrease) 3.6.0 版本新增: 这是用于调整服务器端连接限流器(一种基于令牌、可选概率丢弃的限速机制)的参数之一。此参数定义了要减少的丢弃概率。限流器每隔 connectionFreezeTime 毫秒检查一次,如果令牌桶中的令牌数量超过某个阈值,丢弃概率将减少 connectionDropDecrease。该阈值为 connectionMaxTokens * connectionDecreaseRatio。默认值是 0.002。
-
connectionDecreaseRatio : (Java 系统属性: zookeeper.connection_throttle_decrease_ratio) 3.6.0 版本新增: 这是用于调整服务器端连接限流器(一种基于令牌、可选概率丢弃的限速机制)的参数之一。此参数定义了降低丢弃概率的阈值。默认值是 0。
-
zookeeper.connection_throttle_weight_enabled : (仅 Java 系统属性) 3.6.0 版本新增: 限流时是否考虑连接权重。仅当连接限流启用(即 connectionMaxTokens 大于 0)时有用。默认值是 false。
-
zookeeper.connection_throttle_global_session_weight : (仅 Java 系统属性) 3.6.0 版本新增: 全局会话的权重。这是全局会话请求通过连接限流器所需的令牌数量。它必须是一个正整数,且不小于本地会话的权重。默认值是 3。
-
zookeeper.connection_throttle_local_session_weight : (仅 Java 系统属性) 3.6.0 版本新增: 本地会话的权重。这是本地会话请求通过连接限流器所需的令牌数量。它必须是一个正整数,且不大于全局会话或续约会话的权重。默认值是 1。
-
zookeeper.connection_throttle_renew_session_weight : (仅 Java 系统属性) 3.6.0 版本新增: 会话续约的权重。这也是重新连接请求通过限流器所需的令牌数量。它必须是一个正整数,且不小于本地会话的权重。默认值是 2。
-
clientPortListenBacklog : (无 Java 系统属性) 3.4.14, 3.5.5, 3.6.0 版本新增: ZooKeeper 服务器 Socket 的 Socket 积压队列长度。这控制了在服务端排队等待 ZooKeeper 服务器处理的请求数量。超过此长度的连接将收到网络超时(30 秒),这可能会导致 ZooKeeper 会话过期问题。默认情况下,此值未设置 (
-1
),在 Linux 上使用默认积压队列长度50
。此值必须是一个正数。 -
serverCnxnFactory : (Java 系统属性: zookeeper.serverCnxnFactory) 指定 ServerCnxnFactory 实现。要使用基于 TLS 的服务器通信,应将其设置为
NettyServerCnxnFactory
。默认值是NIOServerCnxnFactory
。 -
flushDelay : (Java 系统属性: zookeeper.flushDelay) 延迟刷新提交日志的时间,以毫秒为单位。不影响 maxBatchSize 定义的限制。默认禁用(值为 0)。写入率高的集群可能会看到设置为 10-20 ms 时吞吐量得到改善。
-
maxWriteQueuePollTime : (Java 系统属性: zookeeper.maxWriteQueuePollTime) 如果 flushDelay 已启用,此参数决定了在没有新请求排队时,等待多久(以毫秒为单位)之后执行刷新。默认设置为 flushDelay/3(默认情况下隐含地禁用)。
-
maxBatchSize : (Java 系统属性: zookeeper.maxBatchSize) 在触发提交日志刷新之前,服务器中允许的最大事务数量。不影响 flushDelay 定义的限制。默认值是 1000。
-
enforceQuota : (Java 系统属性: zookeeper.enforceQuota) 3.7.0 版本新增: 强制执行配额检查。当启用此功能,并且客户端在一个 znode 下超出总字节数或子节点数的硬配额时,服务器将强制拒绝请求并回复客户端一个
QuotaExceededException
异常。默认值是: false。更多详情请参阅配额功能。 -
requestThrottleLimit : (Java 系统属性: zookeeper.request_throttle_max_requests) 3.6.0 版本新增: 在 RequestThrottler 开始阻塞之前允许的最大未完成请求总数。设置为 0 时,限流被禁用。默认值是 0。
-
requestThrottleStallTime : (Java 系统属性: zookeeper.request_throttle_stall_time) 3.6.0 版本新增: 线程可以等待被通知可以继续处理请求的最大时间(以毫秒为单位)。默认值是 100。
-
requestThrottleDropStale : (Java 系统属性: request_throttle_drop_stale) 3.6.0 版本新增: 启用时,限流器将丢弃陈旧请求,而不是将其送入请求管道。陈旧请求是由已关闭连接发送的请求,和/或请求延迟高于其关联的 sessionTimeout 的请求。默认值是 true。
-
requestStaleLatencyCheck : (Java 系统属性: zookeeper.request_stale_latency_check) 3.6.0 版本新增: 启用时,如果请求延迟高于其关联的会话超时,则该请求被视为陈旧请求。默认禁用。
-
requestStaleConnectionCheck : (Java 系统属性: zookeeper.request_stale_connection_check) 3.6.0 版本新增: 启用时,如果请求的连接已关闭,则该请求被视为陈旧请求。默认启用。
-
zookeeper.request_throttler.shutdownTimeout : (仅 Java 系统属性) 3.6.0 版本新增: RequestThrottler 在关机期间等待请求队列清空的时间(以毫秒为单位),超过此时间将强制关机。默认值是 10000。
-
advancedFlowControlEnabled : (Java 系统属性: zookeeper.netty.advancedFlowControl.enabled) 基于 ZooKeeper 管道的状态,在 Netty 中使用精确流控,以避免直接缓冲区 OOM(内存溢出)。这将禁用 Netty 中的 AUTO_READ。
-
enableEagerACLCheck : (仅 Java 系统属性: zookeeper.enableEagerACLCheck) 设置为 "true" 时,启用在每个本地服务器上对写请求进行预先 ACL 检查,然后再将请求发送到 Quorum。默认值是 "false"。
-
maxConcurrentSnapSyncs : (Java 系统属性: zookeeper.leader.maxConcurrentSnapSyncs) Leader 或 Follower 同时能服务的最大 SnapSyncs 数量。默认值是 10。
-
maxConcurrentDiffSyncs : (Java 系统属性: zookeeper.leader.maxConcurrentDiffSyncs) Leader 或 Follower 同时能服务的最大 DiffSyncs 数量。默认值是 100。
-
digest.enabled : (仅 Java 系统属性: zookeeper.digest.enabled) 3.6.0 版本新增: 添加摘要功能是为了在 ZooKeeper 从磁盘加载数据库、追赶并跟随 Leader 时检测数据不一致性,它基于 adHash 论文中提到的方法对 DataTree 进行增量哈希检查。
https://cseweb.ucsd.edu/~daniele/papers/IncHash.pdf
这个想法很简单,DataTree 的哈希值会根据数据集的变化进行增量更新。当 Leader 准备事务 (txn) 时,它将基于发生的变化,使用以下公式预计算树的哈希值:
current_hash = current_hash + hash(new node data) - hash(old node data)
如果它是创建新节点,则 hash(旧节点数据) 将为 0;如果它是删除节点操作 (op),则 hash(新节点数据) 将为 0。
该哈希值将与每个事务关联,以表示将事务应用于数据树后预期的哈希值,它将与原始提案一起发送给 Follower。Learner 在将事务应用于数据树后,将实际哈希值与事务中的哈希值进行比较,如果不一致则报告不匹配。
这些摘要值也将与每个事务和快照一起持久化到磁盘上,因此当服务器重启并从磁盘加载数据时,它会进行比较并查看是否存在哈希不匹配,这有助于检测磁盘上的数据丢失问题。
对于实际的哈希函数,我们在内部使用 CRC,它不是一个无冲突的哈希函数,但与无冲突哈希相比更高效,而且冲突的可能性非常非常低,已经可以满足这里的需求。
此功能向后和向前兼容,因此可以安全地进行滚动升级、降级、启用和后续禁用,没有任何兼容性问题。以下是已覆盖和测试的场景:
- 当 Leader 运行新代码而 Follower 运行旧代码时,摘要将附加到每个事务的末尾,Follower 只读取头部和事务数据,事务中的摘要值将被忽略。这不会影响 Follower 读取和处理下一个事务。
- 当 Leader 运行旧代码而 Follower 运行新代码时,摘要不会随事务发送,当 Follower 尝试读取摘要时,会抛出 EOF 异常,该异常会被捕获并优雅处理,摘要值设置为 null。
- 当使用新代码加载旧快照时,尝试读取不存在的摘要值时会抛出 IOException,该异常将被捕获,摘要将被设置为 null,这意味着在加载此快照时我们不会比较摘要,这在滚动升级期间是预期会发生的。
- 当使用旧代码加载新快照时,反序列化数据树后将成功完成,快照文件末尾的摘要值将被忽略。
- 更改标志的滚动重启场景与前面讨论的第 1 和第 2 个场景类似,如果 Leader 启用但 Follower 未启用,摘要值将被忽略,Follower 在运行时不会比较摘要;如果 Leader 禁用但 Follower 启用,Follower 将获得 EOF 异常,该异常会被优雅处理。
注意:当前的摘要计算排除了 /zookeeper 下的节点,这是由于 /zookeeper/quota stat 节点中潜在的不一致性,在该问题修复后我们可以将其包含进去。
默认情况下,此功能是启用的,设置为 "false" 可将其禁用。
-
snapshot.compression.method : (Java 系统属性: zookeeper.snapshot.compression.method) 3.6.0 版本新增: 此属性控制 ZooKeeper 是否应在将快照存储到磁盘之前对其进行压缩(请参阅 ZOOKEEPER-3179)。可能的值包括:
-
snapshot.trust.empty : (Java 系统属性: zookeeper.snapshot.trust.empty) 3.5.6 版本新增: 此属性控制 ZooKeeper 是否应将缺失的快照文件视为无法恢复的致命状态。设置为 true 允许 ZooKeeper 服务器在没有快照文件的情况下恢复。这仅应在从旧版本 ZooKeeper (3.4.x, 3.5.3 之前) 升级时设置,因为这些版本的 ZooKeeper 可能只有事务日志文件而没有快照文件。如果在升级期间设置了该值,我们建议在升级后将该值设置回 false 并重启 ZooKeeper 进程,以便 ZooKeeper 在恢复过程中可以继续进行正常的数据一致性检查。默认值是 false。
-
audit.enable : (Java 系统属性: zookeeper.audit.enable) 3.6.0 版本新增: 默认情况下,审计日志是禁用的。设置为 "true" 可启用它。默认值是 "false"。更多信息请参阅ZooKeeper 审计日志。
-
audit.impl.class : (Java 系统属性: zookeeper.audit.impl.class) 3.6.0 版本新增: 用于实现审计日志记录器的类。默认使用基于 logback 的审计日志记录器 org.apache.zookeeper.audit .Slf4jAuditLogger。更多信息请参阅ZooKeeper 审计日志。
-
largeRequestMaxBytes : (Java 系统属性: zookeeper.largeRequestMaxBytes) 3.6.0 版本新增: 所有正在进行中的大型请求的最大字节总数。如果即将到来的大型请求导致超出此限制,连接将被关闭。默认值是 100 * 1024 * 1024。
-
largeRequestThreshold : (Java 系统属性: zookeeper.largeRequestThreshold) 3.6.0 版本新增: 请求被视为大型请求的大小阈值。如果为 -1,则所有请求都被视为小型请求,从而有效地关闭了大型请求限流。默认值是 -1。
-
outstandingHandshake.limit (仅 Java 系统属性: zookeeper.netty.server.outstandingHandshake.limit) ZooKeeper 中最大正在进行中的 TLS 握手连接数,超过此限制的连接在开始握手之前将被拒绝。此设置不限制最大 TLS 并发,但有助于避免当有太多正在进行的 TLS 握手时因 TLS 握手超时引起的羊群效应。设置为 250 左右就足以避免羊群效应。
-
netty.server.earlyDropSecureConnectionHandshakes (Java 系统属性: zookeeper.netty.server.earlyDropSecureConnectionHandshakes) 如果 ZooKeeper 服务器未完全启动,则在执行 TLS 握手之前丢弃 TCP 连接。这有助于防止重启后服务器被大量并发 TLS 握手淹没。请注意,如果您启用此标志,服务器在未完全启动时将不会响应 'ruok' 命令。
丢弃连接的行为是在 ZooKeeper 3.7 中引入的,并且当时无法禁用。自 3.7.1 和 3.8.0 版本起,此功能默认禁用。
-
throttledOpWaitTime (Java 系统属性: zookeeper.throttled_op_wait_time) 请求在 RequestThrottler 队列中等待的时间,超过此时间请求将被标记为限流。除了被送入其所属服务器的管道以保留所有请求的顺序之外,限流的请求将不被处理。FinalProcessor 将为这些未处理的请求发出错误响应(新的错误码:ZTHROTTLEDOP)。其目的是为了让客户端不要立即重试它们。设置为 0 时,不会限流任何请求。默认值是 0。
-
learner.closeSocketAsync (Java 系统属性: zookeeper.learner.closeSocketAsync) (Java 系统属性: learner.closeSocketAsync)(为向后兼容添加) 3.7.0 版本新增: 启用时,Learner 将异步关闭 Quorum Socket。这对于 TLS 连接很有用,因为关闭 Socket 可能需要很长时间,阻塞关机进程,可能延迟新的 Leader 选举,并使法定人数 (quorum) 不可用。异步关闭 Socket 可以避免阻塞关机进程,即使 Socket 关闭时间很长,并且可以在关闭 Socket 的同时开始新的 Leader 选举。默认值是 false。
-
leader.closeSocketAsync (Java 系统属性: zookeeper.leader.closeSocketAsync) (Java 系统属性: leader.closeSocketAsync)(为向后兼容添加) 3.7.0 版本新增: 启用时,Leader 将异步关闭 Quorum Socket。这对于 TLS 连接很有用,因为关闭 Socket 可能需要很长时间。如果在 ping() 中因为 SyncLimitCheck 失败而发起断开 Follower 连接,则长时间的 Socket 关闭时间将阻塞向其他 Follower 发送 ping。未收到 ping 的其他 Follower 将不会向 Leader 发送会话信息,从而导致会话过期。将此标志设置为 true 可确保定期发送 ping。默认值是 false。
-
learner.asyncSending (Java 系统属性: zookeeper.learner.asyncSending) (Java 系统属性: learner.asyncSending)(为向后兼容添加) 3.7.0 版本新增: Learner 中的数据包发送和接收在关键部分同步完成。不合时宜的网络问题可能导致 Follower 挂起(请参阅 ZOOKEEPER-3575 和 ZOOKEEPER-4074)。新设计将 Learner 中的数据包发送移动到单独的线程并异步发送数据包。新设计通过此参数 (learner.asyncSending) 启用。默认值是 false。
-
forward_learner_requests_to_commit_processor_disabled (Java 系统属性: zookeeper.forward_learner_requests_to_commit_processor_disabled) 设置此属性后,来自 Learner 的请求将不会被加入 CommitProcessor 队列,这有助于节省 Leader 上的资源和 GC 时间。
默认值是 false。
-
serializeLastProcessedZxid.enabled (Java 系统属性: zookeeper.serializeLastProcessedZxid.enabled) 3.9.0 版本新增: 如果启用,ZooKeeper 在快照时序列化 lastProcessedZxid,在恢复时反序列化。默认为 true。要通过管理服务器命令执行快照和恢复,需要启用此功能,因为快照文件名中没有 lastProcessedZxid 可供提取。
此功能向后和向前兼容。以下是不同场景:
-
a. 服务器内部触发的快照 当使用新代码加载旧快照时,尝试读取不存在的 lastProcessedZxid 值时会抛出 EOFException,该异常将被捕获。lastProcessedZxid 将使用快照文件名设置。
b. 当使用旧代码加载新快照时,反序列化摘要值后将成功完成,快照文件末尾的 lastProcessedZxid 将被忽略。lastProcessedZxid 将使用快照文件名设置。
- Leader 和 Follower 之间的同步 在新旧代码中,lastProcessedZxid 都不会被 Leader 序列化和被 Follower 反序列化。它将被设置为 Leader 通过 QuorumPacket 发送的 lastProcessedZxid。
-
通过管理服务器 API 触发的快照 要使快照命令正常工作,需要启用此功能标志。
集群选项
本节中的选项设计用于服务器集群 -- 即部署服务器集群时使用。
- electionAlg : (无 Java 系统属性) 要使用的选举实现。值为 "1" 对应于未认证的基于 UDP 的快速 Leader 选举版本,"2" 对应于经过认证的基于 UDP 的快速 Leader 选举版本,"3" 对应于基于 TCP 的快速 Leader 选举版本。算法 3 在 3.2.0 中成为默认,之前的版本 (3.0.0 和 3.1.0) 也使用算法 1 和 2。
注意
Leader 选举实现 1 和 2 在 3.4.0 版本中已弃用。自 3.6.0 版本起,只有 FastLeaderElection 可用,如果您要升级,必须关闭所有服务器并使用 electionAlg=3 重新启动它们(或从配置文件中删除该行)。>
- maxTimeToWaitForEpoch : (Java 系统属性: zookeeper.leader.maxTimeToWaitForEpoch) 3.6.0 版本新增: Leader 激活时等待 Voter 发送 Epoch 的最长时间。如果 Leader 从其 Voter 之一接收到 LOOKING 通知,并且在 maxTimeToWaitForEpoch 内未从大多数节点接收到 Epoch 数据包,则它将进入 LOOKING 状态并重新选举 Leader。可以调整此参数以减少法定人数或服务器不可用时间,它可以设置得远小于 initLimit * tickTime。在跨数据中心环境中,可以将其设置为 2 秒左右。
-
initLimit : (无 Java 系统属性) 允许 Follower 连接并同步到 Leader 的时间量,以 Tick 为单位(参见 tickTime)。如果 ZooKeeper 管理的数据量很大,请根据需要增加此值。
-
connectToLearnerMasterLimit : (Java 系统属性: zookeeper.connectToLearnerMasterLimit) 在 Leader 选举后允许 Follower 连接到 Leader 的时间量,以 Tick 为单位(参见 tickTime)。默认为 initLimit 的值。当 initLimit 很高时使用,这样连接 Learner Master 不会导致更高的超时。
-
leaderServes : (Java 系统属性: zookeeper.leaderServes) Leader 是否接受客户端连接。默认值是 "yes"。Leader 机器协调更新。为了获得更高的更新吞吐量,同时稍微牺牲读取吞吐量,可以将 Leader 配置为不接受客户端并专注于协调。此选项默认值为 yes,这意味着 Leader 将接受客户端连接。
注意
当您的集群中有三个以上的 ZooKeeper 服务器时,强烈建议开启 Leader 选举。
- server.x=[hostname]:nnnnn[:nnnnn] 等 : (无 Java 系统属性) 组成 ZooKeeper 集群的服务器。服务器启动时,通过查找数据目录中的 myid 文件来确定自己是哪个服务器。该文件包含 ASCII 格式的服务器编号,应与此设置左侧 server.x 中的 x 匹配。客户端使用的 ZooKeeper 服务器列表必须与每个 ZooKeeper 服务器拥有的 ZooKeeper 服务器列表匹配。有两个端口号 nnnnn。第一个用于 Follower 连接 Leader,第二个用于 Leader 选举。如果您想在单台机器上测试多个服务器,则可以为每个服务器使用不同的端口。
自 ZooKeeper 3.6.0 版本起,可以为每个 ZooKeeper 服务器指定多个地址(请参阅 ZOOKEEPER-3188)。要启用此功能,必须将 multiAddress.enabled 配置属性设置为 true。这有助于提高可用性并增加 ZooKeeper 的网络层面弹性。当服务器使用多个物理网络接口时,ZooKeeper 能够绑定到所有接口,并在发生网络错误时运行时切换到工作接口。不同的地址可以在配置中使用管道符 ('|') 指定。一个使用多个地址的有效配置如下:
server.1=zoo1-net1:2888:3888|zoo1-net2:2889:3889 server.2=zoo2-net1:2888:3888|zoo2-net2:2889:3889 server.3=zoo3-net1:2888:3888|zoo3-net2:2889:3889
注意
启用此功能后,Quorum 协议(ZooKeeper 服务器-服务器协议)将会改变。用户不会注意到这一点,当任何人使用新配置启动 ZooKeeper 集群时,一切都将正常工作。但是,如果旧 ZooKeeper 集群不支持 multiAddress 功能(和新的 Quorum 协议),则在滚动升级期间无法启用此功能并指定多个地址。如果您需要此功能,但还需要从旧于 3.6.0 的 ZooKeeper 集群进行滚动升级,则需要先在不启用 MultiAddress 功能的情况下进行滚动升级,然后进行单独的滚动重启,使用其中 multiAddress.enabled 设置为 true 并提供多个地址的新配置。
- syncLimit : (无 Java 系统属性) 允许 Follower 与 ZooKeeper 同步的时间量,以 Tick 为单位(参见 tickTime)。如果 Follower 落后 Leader 太远,它们将被断开。
-
group.x=nnnnn[:nnnnn] : (无 Java 系统属性) 启用分层法定人数 (quorum) 构建。"x" 是一个组标识符,等号后面的数字对应于服务器标识符。赋值的左侧是用冒号分隔的服务器标识符列表。请注意,组必须是不相交的,并且所有组的并集必须是 ZooKeeper 集群。您可以在此处找到一个示例。
-
weight.x=nnnnn : (无 Java 系统属性) 与 "group" 一起使用,在组建法定人数 (quorum) 时为服务器分配权重。该值对应于服务器在投票时的权重。ZooKeeper 的某些部分需要投票,例如 Leader 选举和原子广播协议。默认情况下,服务器的权重是 1。如果配置定义了组,但没有权重,则将为所有服务器分配值 1。您可以在此处找到一个示例。
-
cnxTimeout : (Java 系统属性: zookeeper.cnxTimeout) 设置打开连接进行 Leader 选举通知的超时值。仅在使用 electionAlg 3 时适用。
注意
默认值是 5 秒。
- quorumCnxnTimeoutMs : (Java 系统属性: zookeeper.quorumCnxnTimeoutMs) 设置连接进行 Leader 选举通知的读取超时值。仅在使用 electionAlg 3 时适用。
注意
默认值是 -1,此时将使用 syncLimit * tickTime 作为超时。
- standaloneEnabled : (无 Java 系统属性) 3.5.0 版本新增: 设置为 false 时,单个服务器可以在副本模式下启动,独立的参与者可以与 Observer 一起运行,集群可以重新配置缩减到一个节点,也可以从一个节点扩展。为了向后兼容,默认值是 true。可以使用 QuorumPeerConfig 的 setStandaloneEnabled 方法设置,也可以在服务器配置文件中添加 "standaloneEnabled=false" 或 "standaloneEnabled=true" 进行设置。
-
reconfigEnabled : (无 Java 系统属性) 3.5.3 版本新增: 此参数控制是否启用动态重新配置功能。启用此功能后,用户可以通过 ZooKeeper 客户端 API 或 ZooKeeper 命令行工具执行重新配置操作,前提是用户被授权执行此类操作。禁用此功能后,任何用户(包括超级用户)都无法执行重新配置。任何重新配置尝试都将返回错误。"reconfigEnabled" 选项可以在服务器配置文件中设置为 "reconfigEnabled=false" 或 "reconfigEnabled=true",或者使用 QuorumPeerConfig 的 setReconfigEnabled 方法设置。默认值是 false。如果存在,该值在整个集群的每个服务器上应保持一致。在某些服务器上将值设置为 true 而在其他服务器上设置为 false 将导致不一致的行为,具体取决于哪个服务器被选举为 Leader。如果 Leader 设置为 "reconfigEnabled=true",则集群将启用重新配置功能。如果 Leader 设置为 "reconfigEnabled=false",则集群将禁用重新配置功能。因此建议集群中的服务器为 "reconfigEnabled" 设置一致的值。
-
4lw.commands.whitelist : (Java system property: zookeeper.4lw.commands.whitelist) 3.5.3 新增: 用户希望使用的、逗号分隔的四字命令列表。有效的四字命令必须包含在此列表中,否则 ZooKeeper 服务器将不会启用该命令。默认情况下,白名单仅包含 zkServer.sh 使用的 "srvr" 命令。其余的四字命令默认是禁用的:尝试使用它们将获得响应 ".... is not executed because it is not in the whitelist."。以下是启用 stat、ruok、conf 和 isro 命令而禁用其余四字命令的配置示例:
4lw.commands.whitelist=stat, ruok, conf, isro
如果你确实需要默认启用所有四字命令,可以使用星号选项,这样就不必在列表中逐个包含每个命令了。例如,这将启用所有四字命令:
4lw.commands.whitelist=*
-
tcpKeepAlive : (Java system property: zookeeper.tcpKeepAlive) 3.5.4 新增: 将此项设置为 true 会在法定人数成员用于执行选举的套接字上设置 TCP keepAlive 标志。这允许法定人数成员之间的连接在可能中断它们的网络基础设施存在时保持连接。某些 NAT 和防火墙可能会终止长时间运行或空闲的连接或使其丢失状态。启用此选项依赖于操作系统级别的设置才能正常工作,请检查你的操作系统的 TCP keepalive 相关选项以获取更多信息。默认为 false。
-
clientTcpKeepAlive : (Java system property: zookeeper.clientTcpKeepAlive) 3.6.1 新增: 将此项设置为 true 会在客户端套接字上设置 TCP keepAlive 标志。一些损坏的网络基础设施可能会丢失关闭客户端发送的 FIN 包。这些从未关闭的客户端套接字会导致操作系统资源泄漏。启用此选项可以通过空闲检查终止这些僵尸套接字。启用此选项依赖于操作系统级别的设置才能正常工作,请检查你的操作系统的 TCP keepalive 相关选项以获取更多信息。默认为 false。请注意它与 tcpKeepAlive 的区别。它应用于客户端套接字,而 tcpKeepAlive 用于法定人数成员使用的套接字。目前,此选项仅在使用默认的
NIOServerCnxnFactory
时可用。 -
electionPortBindRetry : (仅 Java 系统属性: zookeeper.electionPortBindRetry) 当 ZooKeeper 服务器绑定 Leader 选举端口失败时,此属性设置最大重试次数。此类错误可能是临时的且可恢复的,例如 ZOOKEEPER-3320 中描述的 DNS 问题,也可能是不可重试的,例如端口已被占用。对于瞬时错误,此属性可以提高 ZooKeeper 服务器的可用性并帮助其自行恢复。默认值 3。在容器环境中,特别是在 Kubernetes 中,应增加此值或将其设置为 0(无限重试)以克服与 DNS 名称解析相关的问题。
-
observer.reconnectDelayMs : (Java system property: zookeeper.observer.reconnectDelayMs) 当 Observer 与 Leader 失去连接时,它会等待指定的值,然后尝试与 Leader 重新连接,这样整个 Observer 集群就不会同时尝试运行 Leader 选举并重新连接到 Leader。默认为 0 ms。
-
observer.election.DelayMs : (Java system property: zookeeper.observer.election.DelayMs) 在断开连接时延迟 Observer 参与 Leader 选举,以防止在此过程中给投票节点带来意外的额外负载。默认为 200 ms。
-
localSessionsEnabled and localSessionsUpgradingEnabled : 3.5 新增: 可选值为 true 或 false。它们的默认值为 false。通过设置 localSessionsEnabled=true 开启本地会话功能。开启 localSessionsUpgradingEnabled 可以在需要时(例如创建临时节点)自动将本地会话升级为全局会话,这仅在 localSessionsEnabled 启用时有效。
加密、身份验证、授权选项
本节中的选项允许控制服务执行的加密/身份验证/授权。
除了此页面之外,你还可以在程序员指南中找到有关客户端配置的有用信息。ZooKeeper Wiki 上也有关于ZooKeeper SSL 支持和ZooKeeper 的 SASL 身份验证的有用页面。
-
DigestAuthenticationProvider.enabled : (Java system property: zookeeper.DigestAuthenticationProvider.enabled) 3.7 新增: 确定是否启用
digest
身份验证提供程序。默认值为 true 以保持向后兼容性,但如果未使用此提供程序,则禁用它可能是一个好主意,因为它可能导致审计日志中出现误导性条目(参见 ZOOKEEPER-3979) -
DigestAuthenticationProvider.superDigest : (Java system property: zookeeper.DigestAuthenticationProvider.superDigest) 此功能默认 禁用。3.2 新增: 使 ZooKeeper 集群管理员能够作为 "超级" 用户访问 znode 层次结构。特别是,对于作为超级用户进行身份验证的用户,不会进行 ACL 检查。org.apache.zookeeper.server.auth.DigestAuthenticationProvider 可用于生成 superDigest,以参数 "super
" 调用它:"。在启动集群中的每个服务器时,将生成的 "super:" 作为系统属性值提供。从 ZooKeeper 客户端向 ZooKeeper 服务器进行身份验证时,传递方案 "digest" 和认证数据 "super: "。请注意,摘要认证(digest auth)以明文形式将认证数据传递给服务器,明智的做法是仅在 localhost(不在网络上)或通过加密连接使用此身份验证方法。 -
DigestAuthenticationProvider.digestAlg : (Java system property: zookeeper.DigestAuthenticationProvider.digestAlg) 3.7.0 新增: 设置 ACL 摘要算法。默认值是:
SHA1
,由于安全问题,将来会被弃用。在所有服务器中将此属性设置为相同的值。-
如何支持其他更多算法?
-
通过指定:
security.provider.<n>=<provider class name>
修改$JAVA_HOME/jre/lib/security/java.security
下的java.security
配置文件。For example: set zookeeper.DigestAuthenticationProvider.digestAlg=RipeMD160 security.provider.3=org.bouncycastle.jce.provider.BouncyCastleProvider
-
将 jar 文件复制到
$JAVA_HOME/jre/lib/ext/
下。For example: copy bcprov-jdk18on-1.60.jar to $JAVA_HOME/jre/lib/ext/
-
-
如何从一个摘要算法迁移到另一个?
-
- 迁移到新算法时重新生成
superDigest
。
- 迁移到新算法时重新生成
-
- 对已使用旧算法摘要认证的 znode 进行
SetAcl
操作。
- 对已使用旧算法摘要认证的 znode 进行
-
-
-
IPAuthenticationProvider.usexforwardedfor : (Java system property: zookeeper.IPAuthenticationProvider.usexforwardedfor) 3.9.3 新增: IPAuthenticationProvider 使用客户端 IP 地址验证用户。默认情况下,它读取 Host HTTP 头来检测客户端 IP 地址。在某些代理配置中,代理服务器会向请求添加 X-Forwarded-For 头,以提供原始客户端请求的 IP 地址。通过启用 ZooKeeper 设置 usexforwardedfor,将优先使用 X-Forwarded-For 而不是标准的 Host 头。默认值为 false。
-
X509AuthenticationProvider.superUser : (Java system property: zookeeper.X509AuthenticationProvider.superUser) 支持 SSL 的方式,使 ZooKeeper 集群管理员能够作为 "超级" 用户访问 znode 层次结构。当此参数设置为 X500 主体名称时,只有经过该主体身份验证的客户端才能绕过 ACL 检查并拥有所有 znode 的完全权限。
-
zookeeper.superUser : (Java system property: zookeeper.superUser) 类似于 zookeeper.X509AuthenticationProvider.superUser,但它是针对基于 SASL 登录的通用设置。它存储可以作为 "超级" 用户访问 znode 层次结构的用户名称。可以使用 zookeeper.superUser.[suffix] 表示法指定多个 SASL 超级用户,例如:
zookeeper.superUser.1=...
。 -
ssl.authProvider : (Java system property: zookeeper.ssl.authProvider) 指定用于安全客户端身份验证的 org.apache.zookeeper.auth.X509AuthenticationProvider 子类。这对于不使用 JKS 的证书密钥基础设施非常有用。可能需要扩展 javax.net.ssl.X509KeyManager 和 javax.net.ssl.X509TrustManager 才能从 SSL 栈获得所需行为。要配置 ZooKeeper 服务器使用自定义提供程序进行身份验证,请为自定义 AuthenticationProvider 选择一个方案名称,并将属性 zookeeper.authProvider.[scheme] 设置为自定义实现的完全限定类名。这将把提供程序加载到 ProviderRegistry 中。然后设置此属性 zookeeper.ssl.authProvider=[scheme],该提供程序将用于安全身份验证。
-
zookeeper.ensembleAuthName : (仅 Java 系统属性: zookeeper.ensembleAuthName) 3.6.0 新增: 指定一个逗号分隔的有效集群名称/别名列表。客户端可以提供它打算连接的集群名称作为方案 "ensemble" 的凭证。EnsembleAuthenticationProvider 将根据接收连接请求的集群的名称/别名列表检查凭证。如果凭证不在列表中,连接请求将被拒绝。这可以防止客户端意外连接到错误的集群。
-
sessionRequireClientSASLAuth : (Java system property: zookeeper.sessionRequireClientSASLAuth) 3.6.0 新增: 设置为 true 时,ZooKeeper 服务器将只接受通过 SASL 与服务器进行身份验证的客户端的连接和请求。未配置 SASL 身份验证的客户端,或配置了 SASL 但身份验证失败(即使用无效凭证)的客户端将无法与服务器建立会话。在这种情况下,将返回一个类型的错误码 (-124),Java 和 C 客户端此后将关闭与服务器的会话,不会再尝试重新连接。
此配置是 enforce.auth.enabled=true 和 enforce.auth.scheme=sasl 的简写形式。
默认情况下,此功能已禁用。希望选择加入的用户可以通过将 sessionRequireClientSASLAuth 设置为 true 来启用此功能。
此功能会覆盖
zookeeper.allowSaslFailedClients 选项,因此即使服务器配置为允许 SASL 身份验证失败的客户端登录,如果启用此功能,客户端也无法与服务器建立会话。 -
enforce.auth.enabled : (Java 系统属性 : zookeeper.enforce.auth.enabled) 3.7.0 新增: 设置为 true 时,ZooKeeper 服务器将只接受通过配置的身份验证方案与服务器进行身份验证的客户端的连接和请求。可以使用属性 enforce.auth.schemes 配置身份验证方案。未配置服务器端配置的任何身份验证方案,或已配置但身份验证失败(即使用无效凭证)的客户端将无法与服务器建立会话。在这种情况下,将返回一个类型的错误码 (-124),Java 和 C 客户端此后将关闭与服务器的会话,不会再尝试重新连接。
默认情况下,此功能已禁用。希望选择加入的用户可以通过将 enforce.auth.enabled 设置为 true 来启用此功能。
当 enforce.auth.enabled=true 且 enforce.auth.schemes=sasl 时,
zookeeper.allowSaslFailedClients 配置将被覆盖。因此,即使服务器配置为允许 SASL 身份验证失败的客户端登录,如果启用此功能并使用 sasl 作为身份验证方案,客户端也无法与服务器建立会话。 -
enforce.auth.schemes : (Java 系统属性 : zookeeper.enforce.auth.schemes) 3.7.0 新增: 逗号分隔的身份验证方案列表。客户端在进行任何 ZooKeeper 操作之前,必须至少通过一种身份验证方案进行身份验证。此属性仅在 enforce.auth.enabled 设置为 true 时使用。
-
sslQuorum : (Java system property: zookeeper.sslQuorum) 3.5.5 新增: 启用加密的法定人数(Quorum)通信。默认值为
false
。启用此功能时,请考虑同时启用 leader.closeSocketAsync 和 learner.closeSocketAsync,以避免关闭 SSL 连接时可能出现的套接字关闭时间过长的问题。 -
ssl.keyStore.location and ssl.keyStore.password and ssl.quorum.keyStore.location and ssl.quorum.keyStore.password : (Java system properties: zookeeper.ssl.keyStore.location and zookeeper.ssl.keyStore.password and zookeeper.ssl.quorum.keyStore.location and zookeeper.ssl.quorum.keyStore.password) 3.5.5 新增: 指定 Java 密钥库文件的路径,该文件包含用于客户端和法定人数 TLS 连接的本地凭据,以及解锁该文件的密码。
-
ssl.keyStore.passwordPath and ssl.quorum.keyStore.passwordPath : (Java system properties: zookeeper.ssl.keyStore.passwordPath and zookeeper.ssl.quorum.keyStore.passwordPath) 3.8.0 新增: 指定包含密钥库密码的文件路径。从文件读取密码优先于显式密码属性。
-
ssl.keyStore.type and ssl.quorum.keyStore.type : (Java system properties: zookeeper.ssl.keyStore.type and zookeeper.ssl.quorum.keyStore.type) 3.5.5 新增: 指定客户端和法定人数密钥库的文件格式。值:JKS、PEM、PKCS12 或 null(通过文件名检测)。默认值:null。3.5.10, 3.6.3, 3.7.0 新增: 添加了 BCFKS 格式。
-
ssl.trustStore.location and ssl.trustStore.password and ssl.quorum.trustStore.location and ssl.quorum.trustStore.password : (Java system properties: zookeeper.ssl.trustStore.location and zookeeper.ssl.trustStore.password and zookeeper.ssl.quorum.trustStore.location and zookeeper.ssl.quorum.trustStore.password) 3.5.5 新增: 指定 Java 信任库文件的路径,该文件包含用于客户端和法定人数 TLS 连接的远程凭据,以及解锁该文件的密码。
-
ssl.trustStore.passwordPath and ssl.quorum.trustStore.passwordPath : (Java system properties: zookeeper.ssl.trustStore.passwordPath and zookeeper.ssl.quorum.trustStore.passwordPath) 3.8.0 新增: 指定包含信任库密码的文件路径。从文件读取密码优先于显式密码属性。
-
ssl.trustStore.type and ssl.quorum.trustStore.type : (Java system properties: zookeeper.ssl.trustStore.type and zookeeper.ssl.quorum.trustStore.type) 3.5.5 新增: 指定客户端和法定人数信任库的文件格式。值:JKS、PEM、PKCS12 或 null(通过文件名检测)。默认值:null。3.5.10, 3.6.3, 3.7.0 新增: 添加了 BCFKS 格式。
-
ssl.protocol and ssl.quorum.protocol : (Java system properties: zookeeper.ssl.protocol and zookeeper.ssl.quorum.protocol) 3.5.5 新增: 指定在客户端和法定人数 TLS 协商中使用的协议。默认值:取决于使用的 Java 运行时版本,为 TLSv1.3 或 TLSv1.2。
-
ssl.enabledProtocols and ssl.quorum.enabledProtocols : (Java system properties: zookeeper.ssl.enabledProtocols and zookeeper.ssl.quorum.enabledProtocols) 3.5.5 新增: 指定在客户端和法定人数 TLS 协商中启用的协议。默认值:如果
protocol
属性的值为 TLSv1.3,则为 TLSv1.3, TLSv1.2。如果protocol
为 TLSv1.2,则为 TLSv1.2。 -
ssl.ciphersuites and ssl.quorum.ciphersuites : (Java system properties: zookeeper.ssl.ciphersuites and zookeeper.ssl.quorum.ciphersuites) 3.5.5 新增: 指定在客户端和法定人数 TLS 协商中启用的密码套件。默认值:启用的密码套件取决于使用的 Java 运行时版本。
-
ssl.context.supplier.class and ssl.quorum.context.supplier.class : (Java system properties: zookeeper.ssl.context.supplier.class and zookeeper.ssl.quorum.context.supplier.class) 3.5.5 新增: 指定在客户端和法定人数 SSL 通信中用于创建 SSL 上下文的类。这允许你使用自定义 SSL 上下文并实现以下场景:
- 使用硬件密钥库,通过 PKCS11 或类似方式加载。
- 你无法访问软件密钥库,但可以从容器中检索已构建的 SSLContext。默认值:null
-
ssl.hostnameVerification and ssl.quorum.hostnameVerification : (Java system properties: zookeeper.ssl.hostnameVerification and zookeeper.ssl.quorum.hostnameVerification) 3.5.5 新增: 指定在客户端和法定人数 TLS 协商过程中是否启用主机名验证。建议仅出于测试目的禁用此功能。默认值:true
-
ssl.crl and ssl.quorum.crl : (Java system properties: zookeeper.ssl.crl and zookeeper.ssl.quorum.crl) 3.5.5 新增: 指定在客户端和法定人数 TLS 协议中是否启用证书吊销列表(Certificate Revocation List)。默认值:false
-
ssl.ocsp and ssl.quorum.ocsp : (Java system properties: zookeeper.ssl.ocsp and zookeeper.ssl.quorum.ocsp) 3.5.5 新增: 指定在客户端和法定人数 TLS 协议中是否启用在线证书状态协议(Online Certificate Status Protocol)。默认值:false
-
ssl.clientAuth and ssl.quorum.clientAuth : (Java system properties: zookeeper.ssl.clientAuth and zookeeper.ssl.quorum.clientAuth) 在 3.5.5 中添加,但在 3.5.7 之前有问题: 指定用于验证客户端 SSL 连接的选项。有效值包括:
- "none":服务器不请求客户端身份验证
- "want":服务器将 "请求" 客户端身份验证
- "need":服务器将 "要求" 客户端身份验证
默认值:"need"
-
ssl.handshakeDetectionTimeoutMillis and ssl.quorum.handshakeDetectionTimeoutMillis : (Java system properties: zookeeper.ssl.handshakeDetectionTimeoutMillis and zookeeper.ssl.quorum.handshakeDetectionTimeoutMillis) 3.5.5 新增: 待定
-
ssl.sslProvider : (Java system property: zookeeper.ssl.sslProvider) 3.9.0 新增: 允许在启用 TLS 时选择客户端-服务器通信中的 SSL 提供程序。Netty-tcnative 本地库已在 ZooKeeper 3.9.0 版本中添加,这使得我们可以在支持的平台上使用 OpenSSL 等本地 SSL 库。请参阅 Netty-tcnative 文档中可用的选项。默认值为 "JDK"。
-
sslQuorumReloadCertFiles : (无 Java 系统属性) 3.5.5, 3.6.0 新增: 允许在文件系统上的证书发生更改时重新加载法定人数 SSL keyStore 和 trustStore,而无需重新启动 ZK 进程。默认值:false
-
client.certReload : (Java system property: zookeeper.client.certReload) 3.7.2, 3.8.1, 3.9.0 新增: 允许在文件系统上的证书发生更改时重新加载客户端 SSL keyStore 和 trustStore,而无需重新启动 ZK 进程。默认值:false
-
client.portUnification: (Java system property: zookeeper.client.portUnification) 指定客户端端口应接受 SSL 连接(使用与安全客户端端口相同的配置)。默认值:false
-
authProvider: (Java system property: zookeeper.authProvider) 你可以为 ZooKeeper 指定多个身份验证提供程序类。通常使用此参数指定 SASL 身份验证提供程序,例如:
authProvider.1=org.apache.zookeeper.server.auth.SASLAuthenticationProvider
-
kerberos.removeHostFromPrincipal (Java system property: zookeeper.kerberos.removeHostFromPrincipal) 你可以指示 ZooKeeper 在身份验证期间从客户端主体名称中移除主机部分。(例如,zk/myhost@EXAMPLE.COM 客户端主体将在 ZooKeeper 中以 zk@EXAMPLE.COM 的身份进行身份验证)默认值:false
-
kerberos.removeRealmFromPrincipal (Java system property: zookeeper.kerberos.removeRealmFromPrincipal) 你可以指示 ZooKeeper 在身份验证期间从客户端主体名称中移除领域部分。(例如,zk/myhost@EXAMPLE.COM 客户端主体将在 ZooKeeper 中以 zk/myhost 的身份进行身份验证)默认值:false
-
kerberos.canonicalizeHostNames (Java system property: zookeeper.kerberos.canonicalizeHostNames) 3.7.0 新增: 指示 ZooKeeper 标准化从 server.x 行提取的服务器主机名。这允许在配置文件中使用例如
CNAME
记录引用服务器,同时仍能启用法定人数成员之间的 SASL Kerberos 身份验证。它本质上是客户端属性 zookeeper.sasl.client.canonicalize.hostname 在法定人数上的对应项。为了向后兼容性,默认值为 false。 -
multiAddress.enabled : (Java system property: zookeeper.multiAddress.enabled) 3.6.0 新增: 从 ZooKeeper 3.6.0 开始,你还可以为每个 ZooKeeper 服务器实例指定多个地址(这可以在集群中并行使用多个物理网络接口时提高可用性)。将此参数设置为 true 将启用此功能。请注意,如果旧的 ZooKeeper 集群版本早于 3.6.0,则在滚动升级期间无法启用此功能。默认值为 false。
-
multiAddress.reachabilityCheckTimeoutMs : (Java system property: zookeeper.multiAddress.reachabilityCheckTimeoutMs) 3.6.0 新增: 从 ZooKeeper 3.6.0 开始,你还可以为每个 ZooKeeper 服务器实例指定多个地址(这可以在集群中并行使用多个物理网络接口时提高可用性)。ZooKeeper 将执行 ICMP ECHO 请求或尝试在目标主机的端口 7 (Echo) 上建立 TCP 连接,以查找可达地址。这仅在配置中提供多个地址时发生。在此属性中,可以设置可达性检查的超时时间(以毫秒为单位)。对不同地址的检查并行进行,因此此处设置的超时时间是检查所有地址可达性所需的最大时间。默认值为 1000。
除非通过设置 multiAddress.enabled=true 启用 MultiAddress 功能,否则此参数无效。
-
fips-mode : (Java system property: zookeeper.fips-mode) 3.8.2 新增: 在 ZooKeeper 中启用 FIPS 兼容模式。如果启用,用于主机名验证的自定义信任管理器(
ZKTrustManager
)将被禁用,以符合 FIPS 要求。因此,法定人数协议中将无法进行主机名验证,但在客户端-服务器通信中仍然可以设置。默认值:true (3.9.0+), false (3.8.x)
实验性选项/功能
当前被认为是实验性的新功能。
-
只读模式服务器 : (Java system property: readonlymode.enabled) 3.4.0 新增: 将此值设置为 true 可启用只读模式服务器支持(默认禁用)。ROM 允许请求 ROM 支持的客户端会话连接到服务器,即使服务器可能与法定人数隔离。在此模式下,ROM 客户端仍然可以从 ZK 服务读取值,但无法写入值也看不到其他客户端的更改。参见 ZOOKEEPER-784 了解更多详情。
-
zookeeper.follower.skipLearnerRequestToNextProcessor : (Java system property: zookeeper.follower.skipLearnerRequestToNextProcessor) 当集群中有连接到 ObserverMaster 的 Observers 时,开启此标志可能有助于减轻 ObserverMaster 的内存压力。如果你的集群没有任何 observers,或者它们没有连接到 ObserverMaster,或者你的 Observer 没有进行太多写入,那么使用此标志不会有帮助。目前此处的更改受此标志保护,以帮助我们对内存收益获得更多信心。从长远来看,我们可能希望移除此标志,并将其行为设置为默认代码路径。
不安全选项
以下选项可能有用,但使用时请小心。每个选项的风险与其变量功能的解释一同说明。
-
forceSync : (Java system property: zookeeper.forceSync) 要求更新在完成处理更新之前同步到事务日志介质。如果此选项设置为 no,ZooKeeper 将不要求更新同步到介质。
-
jute.maxbuffer : (Java system property:jute.maxbuffer)。
- 此选项只能作为 Java 系统属性设置。它没有 zookeeper 前缀。它指定了可以存储在 znode 中的最大数据大小。单位为:字节。默认值为 0xfffff (1048575) 字节,略小于 1M。
- 如果更改此选项,必须在所有服务器和客户端上设置此系统属性,否则将出现问题。
- 当客户端的 jute.maxbuffer 大于服务器端时,客户端想要写入的数据超出服务器端的 jute.maxbuffer,服务器端将得到 java.io.IOException: Len error 错误。
- 当客户端的 jute.maxbuffer 小于服务器端时,客户端想要读取的数据超出客户端的 jute.maxbuffer,客户端将得到 java.io.IOException: Unreasonable length 或 Packet len is out of range! 错误。
- 这实际上是一个健全性检查。ZooKeeper 设计用于存储千字节级别的数据。在生产环境中,不建议将此属性增加超过默认值,原因如下:
- 大尺寸 znode 会导致不必要的延迟峰值,恶化吞吐量
- 大尺寸 znode 会使 Leader 和 Follower 之间的同步时间不可预测且不收敛(有时超时),导致法定人数不稳定
-
jute.maxbuffer.extrasize: (Java system property: zookeeper.jute.maxbuffer.extrasize) 3.5.7 新增: 在处理客户端请求时,ZooKeeper 服务器在将其作为事务持久化之前,会在请求中添加一些额外信息。之前,此额外信息大小固定为 1024 字节。在许多场景下,特别是当 jute.maxbuffer 值大于 1 MB 且请求类型为 multi 时,这个固定大小是不够的。为了处理所有场景,额外信息大小从 1024 字节增加到与 jute.maxbuffer 大小相同,并且也可以通过 jute.maxbuffer.extrasize 进行配置。通常不需要配置此属性,因为默认值是最优值。
-
skipACL : (Java system property: zookeeper.skipACL) 跳过 ACL 检查。这会提高吞吐量,但会将数据树的完全访问权限开放给所有人。
-
quorumListenOnAllIPs : 设置为 true 时,ZooKeeper 服务器将监听来自其对等节点的连接,包括所有可用的 IP 地址,而不仅仅是配置文件中服务器列表中配置的地址。这会影响处理 ZAB 协议和快速 Leader 选举协议的连接。默认值为 false。
-
multiAddress.reachabilityCheckEnabled : (Java system property: zookeeper.multiAddress.reachabilityCheckEnabled) 3.6.0 新增: 从 ZooKeeper 3.6.0 开始,你还可以为每个 ZooKeeper 服务器实例指定多个地址(这可以在集群中并行使用多个物理网络接口时提高可用性)。ZooKeeper 将执行 ICMP ECHO 请求或尝试在目标主机的端口 7 (Echo) 上建立 TCP 连接,以查找可达地址。这仅在配置中提供多个地址时发生。如果你尝试在单台机器上启动大型(例如 11+)集群成员进行测试时遇到 ICMP 速率限制(例如在 macOS 上),可达性检查可能会失败。
默认值为 true。通过将此参数设置为 'false',可以禁用可达性检查。请注意,禁用可达性检查将导致集群在网络问题期间无法正常重新配置自身,因此建议仅在测试期间禁用。
除非通过设置 multiAddress.enabled=true 启用 MultiAddress 功能,否则此参数无效。
禁用数据目录自动创建
3.5 新增: ZooKeeper 服务器的默认行为是,如果在启动时数据目录(配置文件中指定)不存在,则自动创建该目录。这在某些情况下可能不方便甚至危险。以正在运行的服务器为例,如果配置更改中不小心更改了 dataDir 参数。当 ZooKeeper 服务器重新启动时,它将创建此不存在的目录并开始服务——使用空的 znode 命名空间。这种情况可能导致有效的 "脑裂"(split brain)局面(即新无效目录和原始有效数据存储中都有数据)。因此,最好有一个选项来关闭此自动创建行为。通常在生产环境中应该这样做,然而不幸的是,目前的默认遗留行为无法更改,因此必须逐案处理。这留给用户和 ZooKeeper 发行版打包者决定。
运行 zkServer.sh 时,可以通过将环境变量 ZOO_DATADIR_AUTOCREATE_DISABLE 设置为 1 来禁用自动创建。直接从类文件运行 ZooKeeper 服务器时,可以通过在 java 命令行上设置 zookeeper.datadir.autocreate=false 来实现,即 -Dzookeeper.datadir.autocreate=false
禁用此功能后,如果 ZooKeeper 服务器确定所需目录不存在,它将生成错误并拒绝启动。
提供了一个新脚本 zkServer-initialize.sh 以支持此新功能。如果禁用自动创建,用户需要首先安装 ZooKeeper,然后创建数据目录(以及可能的事务日志目录),然后启动服务器。否则,如上一段所述,服务器将不会启动。运行 zkServer-initialize.sh 将创建所需目录,并可选地设置 myid 文件(可选命令行参数)。即使不使用自动创建功能,也可以使用此脚本,这对用户可能有用,因为过去设置(包括创建 myid 文件)一直是用户面临的问题。请注意,此脚本仅确保数据目录存在,它不创建配置文件,但要求存在配置文件才能执行。
启用数据库存在性验证
3.6.0 新增: ZooKeeper 服务器在启动时找不到数据树的默认行为是将 zxid 设置为零并作为投票成员加入法定人数。如果服务器关闭期间发生某些事件(例如恶意的 'rm -rf')删除了数据目录,这可能很危险,因为该服务器可能会帮助选举一个缺少事务的 Leader。启用数据库存在验证将改变启动时找不到数据树的行为:服务器将作为非投票参与者加入集群,直到它能够与 Leader 同步并获取集群数据的最新版本。为了表明预期的空数据树(集群创建),用户应将文件 'initialize' 放在与 'myid' 相同的目录中。此文件将在服务器启动时被检测到并删除。
直接从类文件运行 ZooKeeper 服务器时,可以通过在 java 命令行上设置 zookeeper.db.autocreate=false 来启用初始化验证,即 -Dzookeeper.db.autocreate=false。运行 zkServer-initialize.sh 将创建所需的初始化文件。
性能调优选项
3.5.0 新增: 多个子系统已重构,以提升读取吞吐量。这包括 NIO 通信子系统和请求处理管道(提交处理器)的多线程化。NIO 是默认的客户端/服务器通信子系统。它的线程模型包括 1 个接收器线程、1-N 个选择器线程和 0-M 个套接字 I/O 工作线程。在请求处理管道中,系统可以配置为同时处理多个读取请求,同时保持相同的一致性保证(同一会话的写后读)。提交处理器的线程模型包括 1 个主线程和 0-N 个工作线程。
默认值旨在最大限度地提高专用 ZooKeeper 机器上的读取吞吐量。这两个子系统都需要有足够的线程数量才能达到峰值读取吞吐量。
-
zookeeper.nio.numSelectorThreads : (仅限 Java 系统属性: zookeeper.nio.numSelectorThreads) 3.5.0 新增: NIO 选择器线程的数量。至少需要 1 个选择器线程。对于大量客户端连接,建议使用一个以上的选择器。默认值是 sqrt( CPU 核心数 / 2 )。
-
zookeeper.nio.numWorkerThreads : (仅限 Java 系统属性: zookeeper.nio.numWorkerThreads) 3.5.0 新增: NIO 工作线程的数量。如果配置为 0 个工作线程,选择器线程将直接执行套接字 I/O。默认值是 CPU 核心数的 2 倍。
-
zookeeper.commitProcessor.numWorkerThreads : (仅限 Java 系统属性: zookeeper.commitProcessor.numWorkerThreads) 3.5.0 新增: 提交处理器工作线程的数量。如果配置为 0 个工作线程,主线程将直接处理请求。默认值是 CPU 核心数。
-
zookeeper.commitProcessor.maxReadBatchSize : (仅限 Java 系统属性: zookeeper.commitProcessor.maxReadBatchSize) 从 queuedRequests 中处理的最大读取数,然后切换到处理提交。如果值 < 0(默认值),则每当有本地写操作和待处理提交时,我们就会切换。高的读取批处理大小会延迟提交处理,导致提供陈旧数据。如果已知读取请求是按固定大小的批次到达的,则将该批次大小与此属性值匹配可以平滑队列性能。由于读取是并行处理的,建议将此属性设置为与 zookeeper.commitProcessor.numWorkerThread(默认值是 CPU 核心数)相同或更低。
-
zookeeper.commitProcessor.maxCommitBatchSize : (仅限 Java 系统属性: zookeeper.commitProcessor.maxCommitBatchSize) 在处理读取之前处理的最大提交数。我们会尝试处理尽可能多的远程/本地提交,直到达到此计数。高的提交批处理大小会在处理更多提交时延迟读取。低的提交批处理大小会优先处理读取。仅建议在集群处理高提交率工作负载时设置此属性。如果已知写入请求是按设定的批次数量到达的,则将该批次大小与此属性值匹配可以平滑队列性能。通用方法是将此值设置为等于集群大小,这样在处理每个批次时,当前服务器将可能处理与其某个直接客户端相关的写入。默认值是 "1"。不支持负值和零值。
-
znode.container.checkIntervalMs : (仅限 Java 系统属性) 3.6.0 新增: 检查候选容器节点和 TTL 节点的毫秒级时间间隔。默认值是 "60000"。
-
znode.container.maxPerMinute : (仅限 Java 系统属性) 3.6.0 新增: 每分钟可以删除的最大容器节点和 TTL 节点数量。这可以防止在容器删除过程中出现“羊群效应”(herding)。默认值是 "10000"。
-
znode.container.maxNeverUsedIntervalMs : (仅限 Java 系统属性) 3.6.0 新增: 从未有过子节点的容器被保留的最大毫秒级时间间隔。应足够长,以便客户端创建容器、执行所需的任何工作,然后创建子节点。默认值是 "0",表示从没有子节点的容器永不删除。
调试可观测性配置
3.6.0 新增: 引入以下选项使 ZooKeeper 更易于调试。
-
zookeeper.messageTracker.BufferSize : (仅限 Java 系统属性) 控制 MessageTracker 中存储的最大消息数量。值应为正整数。默认值是 10。MessageTracker 在 3.6.0 中引入,用于记录服务器(追随者或观察者)与领导者之间最近一组消息,当服务器与领导者断开连接时。这些消息集将被转储到 ZooKeeper 的日志文件中,有助于重建断开连接时服务器的状态,并对调试目的很有用。
-
zookeeper.messageTracker.Enabled : (仅限 Java 系统属性) 当设置为 "true" 时,将启用 MessageTracker 来跟踪和记录消息。默认值是 "false"。
AdminServer 配置
3.9.0 新增: 以下选项用于配置 AdminServer。
-
admin.rateLimiterIntervalInMS : (Java 系统属性: zookeeper.admin.rateLimiterIntervalInMS) 用于限制管理命令速率以保护服务器的时间间隔。默认为 5 分钟。
-
admin.snapshot.enabled : (Java 系统属性: zookeeper.admin.snapshot.enabled) 启用快照命令的标志。默认为 true。
-
admin.restore.enabled : (Java 系统属性: zookeeper.admin.restore.enabled) 启用恢复命令的标志。默认为 true。
-
admin.needClientAuth : (Java 系统属性: zookeeper.admin.needClientAuth) 控制是否需要客户端身份验证的标志。使用 x509 身份验证需要设置为 true。默认为 false。
3.7.1 新增: 以下选项用于配置 AdminServer。
- admin.forceHttps : (Java 系统属性: zookeeper.admin.forceHttps) 强制 AdminServer 使用 SSL,从而只允许 HTTPS 流量。默认为禁用。覆盖 admin.portUnification 设置。
3.6.0 新增: 以下选项用于配置 AdminServer。
- admin.portUnification : (Java 系统属性: zookeeper.admin.portUnification) 启用管理端口接受 HTTP 和 HTTPS 流量。默认为禁用。
3.5.0 新增: 以下选项用于配置 AdminServer。
-
admin.enableServer : (Java 系统属性: zookeeper.admin.enableServer) 设置为 "false" 以禁用 AdminServer。默认情况下 AdminServer 是启用的。
-
admin.serverAddress : (Java 系统属性: zookeeper.admin.serverAddress) 内嵌 Jetty 服务器监听的地址。默认为 0.0.0.0。
-
admin.serverPort : (Java 系统属性: zookeeper.admin.serverPort) 内嵌 Jetty 服务器监听的端口。默认为 8080。
-
admin.idleTimeout : (Java 系统属性: zookeeper.admin.idleTimeout) 设置连接在发送或接收数据之前可以等待的最大空闲时间(毫秒)。默认为 30000 毫秒。
-
admin.commandURL : (Java 系统属性: zookeeper.admin.commandURL) 相对于根 URL 列出和发出命令的 URL。默认为 "/commands"。
指标提供者
3.6.0 新增: 以下选项用于配置指标。
默认情况下,ZooKeeper 服务器通过 AdminServer 和 四字命令 (Four Letter Words) 接口暴露有用的指标。
自 3.6.0 起,您可以配置不同的指标提供者,将指标导出到您喜欢的系统。
自 3.6.0 起,ZooKeeper 二进制包捆绑了与 Prometheus.io 的集成。
-
metricsProvider.className : 设置为 "org.apache.zookeeper.metrics.prometheus.PrometheusMetricsProvider" 可启用 Prometheus.io 导出器。
-
metricsProvider.httpHost : 3.8.0 新增: Prometheus.io 导出器将启动一个 Jetty 服务器并监听此地址,默认是 "0.0.0.0"。
-
metricsProvider.httpPort : Prometheus.io 导出器将启动一个 Jetty 服务器并绑定到此端口,默认为 7000。Prometheus 端点将是 http://hostname:httPort/metrics。
-
metricsProvider.exportJvmInfo : 如果此属性设置为 true,Prometheus.io 将导出有关 JVM 的有用指标。默认值是 true。
-
metricsProvider.numWorkerThreads : 3.7.1 新增: 用于报告 Prometheus 摘要指标的工作线程数量。默认值是 1。如果数量小于 1,将使用主线程。
-
metricsProvider.maxQueueSize : 3.7.1 新增: Prometheus 摘要指标报告任务的最大队列大小。默认值是 1000000。
-
metricsProvider.workerShutdownTimeoutMs : 3.7.1 新增: Prometheus 工作线程关闭的超时时间(毫秒)。默认值是 1000ms。
使用 Netty 框架进行通信
Netty 是一个基于 NIO 的客户端/服务器通信框架,它简化了(相比直接使用 NIO)Java 应用程序网络级通信的许多复杂性。此外,Netty 框架内置支持加密(SSL)和身份验证(证书)。这些是可选功能,可以单独开启或关闭。
在 3.5+ 版本中,ZooKeeper 服务器可以通过将环境变量 zookeeper.serverCnxnFactory 设置为 org.apache.zookeeper.server.NettyServerCnxnFactory 来使用 Netty 代替 NIO(默认选项);对于客户端,将 zookeeper.clientCnxnSocket 设置为 org.apache.zookeeper.ClientCnxnSocketNetty。
Quorum TLS
3.5.5 新增
基于 Netty 框架,ZooKeeper 集群可以配置为在其通信通道中使用 TLS 加密。本节介绍如何在法定人数(Quorum)通信上设置加密。
请注意,法定人数 TLS 包括保护领导者选举和法定人数通信协议。
- 创建 SSL 密钥库 JKS 用于存储本地凭证
每个 ZK 实例应创建一个密钥库。
在此示例中,我们生成自签名证书并将其与私钥一起存储在 keystore.jks
中。这适用于测试目的,但在生产环境中,您可能需要官方证书来签署您的密钥。
请注意,别名(-alias
)和可分辨名称(-dname
)必须与关联机器的主机名匹配,否则主机名验证将不起作用。
keytool -genkeypair -alias $(hostname -f) -keyalg RSA -keysize 2048 -dname "cn=$(hostname -f)" -keypass password -keystore keystore.jks -storepass password
- 从密钥库中提取签名的公钥(证书)
此步骤可能仅对自签名证书必要。
keytool -exportcert -alias $(hostname -f) -keystore keystore.jks -file $(hostname -f).cer -rfc
- 创建包含所有 ZooKeeper 实例证书的 SSL 信任库 JKS
所有集群参与者应共享相同的信任库(存储所有接受的证书)。您需要在同一信任库中使用不同的别名来存储多个证书。别名的名称无关紧要。
keytool -importcert -alias [host1..3] -file [host1..3].cer -keystore truststore.jks -storepass password
- 您需要使用
NettyServerCnxnFactory
作为 serverCnxnFactory,因为 NIO 不支持 SSL。将以下配置设置添加到您的zoo.cfg
配置文件中
sslQuorum=true
serverCnxnFactory=org.apache.zookeeper.server.NettyServerCnxnFactory
ssl.quorum.keyStore.location=/path/to/keystore.jks
ssl.quorum.keyStore.password=password
ssl.quorum.trustStore.location=/path/to/truststore.jks
ssl.quorum.trustStore.password=password
- 在日志中验证您的集群是否在 TLS 上运行
INFO [main:QuorumPeer@1789] - Using TLS encrypted quorum communication
INFO [main:QuorumPeer@1797] - Port unification disabled
...
INFO [QuorumPeerListener:QuorumCnxManager$Listener@877] - Creating TLS-only quorum server socket
无需停机升级现有非 TLS 集群
3.5.5 新增
以下是利用端口统一功能将已运行的 ZooKeeper 集群升级到 TLS 而无需停机所需的步骤。
-
为所有 ZK 参与者创建所需的密钥库和信任库,如前一节所述
-
添加以下配置设置并重启第一个节点
sslQuorum=false
portUnification=true
serverCnxnFactory=org.apache.zookeeper.server.NettyServerCnxnFactory
ssl.quorum.keyStore.location=/path/to/keystore.jks
ssl.quorum.keyStore.password=password
ssl.quorum.trustStore.location=/path/to/truststore.jks
ssl.quorum.trustStore.password=password
请注意,TLS 尚未启用,但我们开启了端口统一。
- 在剩余节点上重复步骤 #2。验证您在日志中看到以下条目
INFO [main:QuorumPeer@1791] - Using insecure (non-TLS) quorum communication
INFO [main:QuorumPeer@1797] - Port unification enabled
...
INFO [QuorumPeerListener:QuorumCnxManager$Listener@874] - Creating TLS-enabled quorum server socket
每次节点重启后,您还应再次检查法定人数(quorum)是否恢复正常。
- 在每个节点上启用法定人数 TLS 并进行滚动重启
sslQuorum=true
portUnification=true
- 一旦您验证了整个集群都在 TLS 上运行,就可以禁用端口统一并进行另一次滚动重启
sslQuorum=true
portUnification=false
ZooKeeper 命令
四字命令
ZooKeeper 会响应一小组命令。每个命令都由四个字母组成。您通过 telnet 或 nc 在客户端端口向 ZooKeeper 发出命令。
其中三个比较有趣的命令是:"stat" 提供关于服务器和已连接客户端的一些通用信息,而 "srvr" 和 "cons" 分别提供服务器和连接的扩展详情。
3.5.3 新增: 四字命令在使用前需要明确列入白名单。详情请参阅集群配置部分中描述的 4lw.commands.whitelist。将来,四字命令将弃用,请改用AdminServer。
-
conf : 3.3.0 新增: 打印关于服务配置的详情。
-
cons : 3.3.0 新增: 列出连接到此服务器的所有客户端的完整连接/会话详情。包括接收/发送的数据包数量、会话 ID、操作延迟、执行的最后操作等信息。
-
crst : 3.3.0 新增: 重置所有连接的连接/会话统计信息。
-
dump : 列出未完成的会话和临时节点。
-
envi : 打印关于服务环境的详情
-
ruok : 测试服务器是否处于非错误状态。当白名单启用 ruok 时,如果服务器正在运行,它将响应
imok
,否则将完全不响应。当 ruok 被禁用时,服务器响应:"ruok is not executed because it is not in the whitelist." 响应 "imok" 不一定表示服务器已加入法定人数(quorum),只表示服务器进程处于活动状态并绑定到指定的客户端端口。使用 "stat" 获取关于法定人数状态和客户端连接信息的详情。 -
srst : 重置服务器统计信息。
-
srvr : 3.3.0 新增: 列出服务器的完整详情。
-
stat : 列出服务器和已连接客户端的简要详情。
-
wchs : 3.3.0 新增: 列出服务器观察点(watches)的简要信息。
-
wchc : 3.3.0 新增: 按会话列出服务器观察点的详细信息。这会输出一个包含关联观察点(路径)的会话(连接)列表。注意,根据观察点的数量,此操作可能会非常耗费资源(即影响服务器性能),请谨慎使用。
-
dirs : 3.5.1 新增: 显示快照和日志文件的总大小(字节)
-
wchp : 3.3.0 新增: 按路径列出服务器观察点的详细信息。这会输出一个包含关联会话的路径(znode)列表。注意,根据观察点的数量,此操作可能会非常耗费资源(即影响服务器性能),请谨慎使用。
-
mntr : 3.4.0 新增: 输出可用于监控集群健康状况的变量列表。
$ echo mntr | nc localhost 2185 zk_version 3.4.0 zk_avg_latency 0.7561 - be account to four decimal places zk_max_latency 0 zk_min_latency 0 zk_packets_received 70 zk_packets_sent 69 zk_outstanding_requests 0 zk_server_state leader zk_znode_count 4 zk_watch_count 0 zk_ephemerals_count 0 zk_approximate_data_size 27 zk_followers 4 - only exposed by the Leader zk_synced_followers 4 - only exposed by the Leader zk_pending_syncs 0 - only exposed by the Leader zk_open_file_descriptor_count 23 - only available on Unix platforms zk_max_file_descriptor_count 1024 - only available on Unix platforms
输出兼容 Java properties 格式,并且内容可能会随时间变化(会添加新键)。您的脚本应预期会有变化。注意:有些键是平台特定的,有些键仅由领导者(Leader)导出。输出包含多行,格式如下:
key \t value
-
isro : 3.4.0 新增: 测试服务器是否以只读模式运行。如果处于只读模式,服务器将响应 "ro",如果不是,则响应 "rw"。
-
hash : 3.6.0 新增: 返回与 zxid 关联的树摘要的最新历史记录。
-
gtmk : 以十进制格式获取当前跟踪掩码(trace mask)作为 64 位有符号长整型值。有关可能值的解释,请参阅
stmk
。 -
stmk : 设置当前的跟踪掩码。跟踪掩码是 64 位,其中每一位启用或禁用服务器上的特定类别跟踪日志记录。必须先配置 Logback 以启用
TRACE
级别才能看到跟踪日志消息。跟踪掩码的位对应于以下跟踪日志记录类别。跟踪掩码位值 0b0000000000 未使用,保留供将来使用。 0b0000000010 记录客户端请求,不包括 ping 请求。 0b0000000100 未使用,保留供将来使用。 0b0000001000 记录客户端 ping 请求。 0b0000010000 记录从当前领导者(quorum peer)收到的数据包,不包括 ping 请求。 0b0000100000 记录客户端会话的添加、移除和验证。 0b0001000000 记录将观察点事件发送给客户端会话。 0b0010000000 记录从当前领导者(quorum peer)收到的 ping 数据包。 0b0100000000 未使用,保留供将来使用。 0b1000000000 未使用,保留供将来使用。 64 位值中所有剩余位均未使用,保留供将来使用。通过计算已记录值的按位或来指定多个跟踪日志记录类别。默认跟踪掩码是 0b0100110010。因此,默认情况下,跟踪日志记录包括客户端请求、从领导者接收的数据包和会话。要设置不同的跟踪掩码,请发送一个包含
stmk
四字命令,后跟表示为 64 位有符号长整型值的跟踪掩码的请求。此示例使用 Perlpack
函数构建一个启用上述所有跟踪日志记录类别的跟踪掩码,并将其转换为大端字节序的 64 位有符号长整型值。结果附加到stmk
并使用 netcat 发送到服务器。服务器以十进制格式响应新的跟踪掩码。$ perl -e "print 'stmk', pack('q>', 0b0011111010)" | nc localhost 2181 250
以下是 ruok 命令的一个示例
$ echo ruok | nc 127.0.0.1 5111
imok
AdminServer
3.5.0 新增: AdminServer 是一个内嵌的 Jetty 服务器,为四字命令提供 HTTP 接口。默认情况下,服务器在端口 8080 上启动,通过访问 URL "/commands/[command name]" 来发出命令,例如 http://localhost:8080/commands/stat。命令响应以 JSON 格式返回。与原始协议不同,命令不限于四字名称,并且命令可以有多个名称;例如,"stmk" 也可以称为 "set_trace_mask"。要查看所有可用命令列表,请在浏览器中访问 URL /commands(例如 http://localhost:8080/commands)。有关如何更改端口和 URL 的信息,请参阅AdminServer 配置选项。
AdminServer 默认启用,但可以通过以下方式禁用:
- 将 zookeeper.admin.enableServer 系统属性设置为 false。
- 从 classpath 中移除 Jetty。(如果您想覆盖 ZooKeeper 的 jetty 依赖项,此选项很有用。)
请注意,如果 AdminServer 被禁用,TCP 四字命令接口仍然可用。
为 AdminServer 配置 SSL/TLS
- 生成 keystore.jks 和 truststore.jks,这可以在法定人数 TLS (Quorum TLS) 中找到。
- 将以下配置设置添加到
zoo.cfg
配置文件中
admin.portUnification=true
ssl.quorum.keyStore.location=/path/to/keystore.jks
ssl.quorum.keyStore.password=password
ssl.quorum.trustStore.location=/path/to/truststore.jks
ssl.quorum.trustStore.password=password
- 验证是否能在日志中看到以下条目
2019-08-03 15:44:55,213 [myid:] - INFO [main:JettyAdminServer@123] - Successfully loaded private key from /data/software/cert/keystore.jks
2019-08-03 15:44:55,213 [myid:] - INFO [main:JettyAdminServer@124] - Successfully loaded certificate authority from /data/software/cert/truststore.jks
2019-08-03 15:44:55,403 [myid:] - INFO [main:JettyAdminServer@170] - Started AdminServer on address 0.0.0.0, port 8080 and command URL /commands
可用命令包括:
-
connection_stat_reset/crst: 重置所有客户端连接统计信息。不返回新字段。
-
configuration/conf/config : 打印关于服务配置的基本详情,例如客户端端口、数据目录的绝对路径。
-
connections/cons : 关于客户端与服务器连接的信息。注意,根据客户端连接的数量,此操作可能会非常耗费资源(即影响服务器性能)。返回 "connections",这是一个连接信息对象的列表。
-
hash: 历史摘要列表中的事务(Txn)摘要。每 128 个事务记录一个。返回 "digests",这是一个事务摘要对象的列表。
-
dirs : 关于日志文件目录和快照目录大小(字节)的信息。返回 "datadir_size" 和 "logdir_size"。
-
dump : 关于会话过期和临时节点的信息。注意,根据全局会话和临时节点的数量,此操作可能会非常耗费资源(即影响服务器性能)。以 map 格式返回 "expiry_time_to_session_ids" 和 "session_id_to_ephemeral_paths"。
-
environment/env/envi : 所有定义的环境变量。每个作为其自己的字段返回。
-
get_trace_mask/gtmk : 当前的跟踪掩码。set_trace_mask 的只读版本。详情请参阅四字命令 stmk 的描述。返回 "tracemask"。
-
initial_configuration/icfg : 打印用于启动对等节点的配置文件文本。返回 "initial_configuration"。
-
is_read_only/isro : 如果此服务器处于只读模式,则为 true/false。返回 "read_only"。
-
last_snapshot/lsnp : ZooKeeper 服务器已完成保存到磁盘的最后一个快照的信息。如果在服务器启动到完成保存其第一个快照的初始时间段内调用,该命令将返回启动服务器时读取的快照信息。返回 "zxid" 和 "timestamp",后者使用秒作为时间单位。
-
leader/lead : 如果集群配置为法定人数(quorum)模式,则发出对等节点的当前领导者状态和当前领导者位置。返回 "is_leader"、"leader_id" 和 "leader_ip"。
-
monitor/mntr : 发出各种有用的监控信息。包括性能统计、内部队列信息以及数据树的摘要(等等)。每个作为其自己的字段返回。
-
observer_connection_stat_reset/orst : 重置所有观察者连接统计信息。是 observers 命令的配套命令。不返回新字段。
-
restore/rest : 从当前服务器上的快照输入流恢复数据库。在响应载荷中返回以下数据:"last_zxid": String。注意:此 API 受速率限制(默认每 5 分钟一次),以保护服务器免受过载。
-
ruok : 无操作命令,检查服务器是否正在运行。响应不一定表明服务器已加入法定人数(quorum),只表明管理服务器处于活动状态并绑定到指定端口。不返回新字段。
-
set_trace_mask/stmk : 设置跟踪掩码(因此需要参数)。get_trace_mask 的写入版本。详情请参阅四字命令 stmk 的描述。返回 "tracemask"。
-
server_stats/srvr : 服务器信息。返回多个字段,提供服务器状态的简要概述。
-
snapshot/snap : 在数据目录中拍摄当前服务器的快照并流出数据。可选查询参数:"streaming": Boolean(如果参数不存在,默认为 true)。通过 Http 头返回以下信息:"last_zxid": String "snapshot_size": String。注意:此 API 受速率限制(默认每 5 分钟一次),以保护服务器免受过载。
-
stats/stat : 与 server_stats 相同,但也返回 "connections" 字段(详情请参阅 connections)。注意,根据客户端连接的数量,此操作可能会非常耗费资源(即影响服务器性能)。
-
stat_reset/srst : 重置服务器统计信息。这是 server_stats 和 stats 返回信息的一个子集。不返回新字段。
-
observers/obsr : 关于观察者与服务器连接的信息。总是在领导者(Leader)上可用,如果追随者(Follower)充当学习者主节点(learner master),则在其上可用。返回 "synced_observers" (int) 和 "observers"(每个观察者的属性列表)。
-
system_properties/sysp : 所有定义的系统属性。每个作为其自己的字段返回。
-
voting_view : 提供集群中当前的投票成员。以 map 格式返回 "current_config"。
-
watches/wchc : 按会话聚合的观察点信息。注意,根据观察点的数量,此操作可能会非常耗费资源(即影响服务器性能)。以 map 格式返回 "session_id_to_watched_paths"。
-
watches_by_path/wchp : 按路径聚合的观察点信息。注意,根据观察点的数量,此操作可能会非常耗费资源(即影响服务器性能)。以 map 格式返回 "path_to_session_ids"。
-
watch_summary/wchs : 汇总的观察点信息。返回 "num_total_watches"、"num_paths" 和 "num_connections"。
-
zabstate : 对等节点当前运行的 Zab 协议阶段及其是否为投票成员。对等节点可以处于以下阶段之一:选举 (ELECTION)、发现 (DISCOVERY)、同步 (SYNCHRONIZATION)、广播 (BROADCAST)。返回字段 "voting" 和 "zabstate"。
数据文件管理
ZooKeeper 将其数据存储在数据目录中,将其事务日志存储在事务日志目录中。默认情况下,这两个目录是相同的。服务器可以(也应该)配置为将事务日志文件存储在与数据文件分开的目录中。当事务日志位于专用日志设备上时,吞吐量会增加,延迟会降低。
数据目录
此目录中包含两到三个文件
- myid - 包含一个人类可读的 ASCII 文本整数,表示服务器 ID。
- initialize - 存在表示预期没有数据树。数据树创建后会被清理。
- snapshot.
- 包含数据树的模糊快照。
每个 ZooKeeper 服务器都有一个唯一的 ID。此 ID 用于两个地方:myid 文件和配置文件。myid 文件标识对应给定数据目录的服务器。配置文件列出了由其服务器 ID 标识的每个服务器的联系信息。当 ZooKeeper 服务器实例启动时,它从 myid 文件中读取其 ID,然后使用该 ID 从配置文件中读取信息,查找应监听的端口。
存储在数据目录中的 snapshot 文件是模糊快照,因为在 ZooKeeper 服务器拍摄快照期间,数据树会发生更新。snapshot 文件名后缀是 zxid,即 ZooKeeper 事务 ID,是快照开始时最后提交事务的 ID。因此,快照包含在快照进行过程中发生的数据树更新的子集。因此,快照可能不对应于实际存在的任何数据树,因此我们将其称为模糊快照。尽管如此,ZooKeeper 仍可以使用此快照进行恢复,因为它利用了其更新的幂等性(idempotent nature)。通过对照模糊快照重放事务日志,ZooKeeper 可以获取日志结束时的系统状态。
日志目录
日志目录包含 ZooKeeper 事务日志。在进行任何更新之前,ZooKeeper 确保表示该更新的事务被写入非易失性存储。当写入当前日志文件的事务数量达到某个(可变)阈值时,将启动一个新的日志文件。阈值使用影响快照频率的相同参数计算(参见上面的 snapCount 和 snapSizeLimitInKb)。日志文件的后缀是写入该日志的第一个 zxid。
文件管理
快照和日志文件的格式在独立 ZooKeeper 服务器和不同配置的复制 ZooKeeper 服务器之间不会改变。因此,您可以将这些文件从正在运行的复制 ZooKeeper 服务器拉取到具有独立 ZooKeeper 服务器的开发机器上进行故障排除。
使用较旧的日志和快照文件,您可以查看 ZooKeeper 服务器的先前状态,甚至恢复该状态。
ZooKeeper 服务器创建快照和日志文件,但从不删除它们。数据和日志文件的保留策略是在 ZooKeeper 服务器外部实现的。服务器本身只需要最新的完整模糊快照、其后的所有日志文件以及其前的最后一个日志文件。后一个要求是必要的,以便包含在此快照开始后发生但在当时写入到现有日志文件中的更新。这是可能的,因为在 ZooKeeper 中,快照和日志滚动是相对独立进行的。有关设置保留策略和维护 ZooKeeper 存储的更多详情,请参阅本文档的维护部分。
注意
存储在这些文件中的数据未加密。如果在 ZooKeeper 中存储敏感数据,需要采取必要措施防止未经授权的访问。这些措施是 ZooKeeper 外部的(例如,控制对文件的访问),并取决于部署它的具体设置。
恢复 - TxnLogToolkit
更多详情可在此处找到。
应避免的事项
以下是一些通过正确配置 ZooKeeper 可以避免的常见问题。
-
不一致的服务器列表 : 客户端使用的 ZooKeeper 服务器列表必须与每个 ZooKeeper 服务器拥有的列表匹配。如果客户端列表是实际列表的子集,则情况尚可,但如果客户端持有的 ZooKeeper 服务器列表属于不同的 ZooKeeper 集群,则情况将非常异常。此外,每个 ZooKeeper 服务器配置文件中的服务器列表应彼此一致。
-
事务日志放置位置不正确 : ZooKeeper 性能最关键的部分是事务日志。ZooKeeper 在返回响应之前将事务同步到介质。专用事务日志设备是实现持续良好性能的关键。将日志放在繁忙的设备上会对性能产生不利影响。如果您只有一个存储设备,请增加 snapCount,以便减少生成快照文件的频率;这并不能消除问题,但可以为事务日志提供更多资源。
-
不正确的 Java 堆大小:你应该特别注意正确设置你的 Java 最大堆大小。特别是,你不应该造成 ZooKeeper 交换到磁盘的情况。磁盘对 ZooKeeper 来说是致命的。一切操作都是有序的,因此如果处理一个请求导致磁盘交换,所有其他排队的请求可能也会这样做。磁盘。不要交换。在你的估算中要保守一些:如果你有 4GB 内存,不要将 Java 最大堆大小设置到 6GB 甚至 4GB。例如,在一台 4GB 的机器上,你更可能会使用 3GB 的堆,因为操作系统和缓存也需要内存。估算你的系统所需堆大小最好也是唯一推荐的做法是运行负载测试,然后确保你的使用情况远远低于会导致系统发生交换的使用限制。
-
公开可访问的部署:ZooKeeper 集群预期应运行在信任的计算环境中。因此建议将 ZooKeeper 部署在防火墙后。
最佳实践
为了获得最佳效果,请注意以下良好 ZooKeeper 实践列表
对于多租户安装,请参见详细介绍 ZooKeeper 的 "chroot" 支持的章节,这在部署许多对接单个 ZooKeeper 集群的应用程序/服务时会非常有用。