ZooKeeper 管理员指南
部署与管理指南
- 部署
- 管理
部署
本节包含关于部署Zookeeper的信息,涵盖以下主题:
前两部分假设您有兴趣在生产环境(如数据中心)中安装ZooKeeper。最后一部分则介绍在有限场景下(如评估、测试或开发)而非生产环境中搭建ZooKeeper的情况。
系统要求
支持的平台
ZooKeeper由多个组件组成。部分组件得到广泛支持,而其他组件仅适用于少数平台。
- Client 是Java客户端库,应用程序通过它连接到ZooKeeper集群。
- Server 是运行在ZooKeeper集群节点上的Java服务器。
- 原生客户端是用C语言实现的客户端,类似于Java客户端,应用程序通过它连接到ZooKeeper集群。
- 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服务器集群的形式运行。三台ZooKeeper服务器是推荐的最小集群规模,同时建议它们运行在不同的机器上。在雅虎,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堆大小。这对避免交换非常重要,交换会严重降低ZooKeeper性能。要确定正确的值,请使用负载测试,并确保您远低于会导致交换的使用限制。保守起见 - 对于4GB的机器,最大堆大小使用3GB。
-
Install the ZooKeeper Server Package. It can be downloaded from: http://zookeeper.apache.org/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很直观,对于每台服务器,您需要先指定仲裁端口,然后是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管理Bean,支持通过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的可靠性基于两个基本假设。
- 在部署环境中,只有少数服务器会出现故障。此处的故障指的是机器崩溃,或是导致服务器与多数节点断连的网络错误。
- 部署的机器运行正常。运行正常意味着正确执行代码、时钟工作正常,且存储和网络组件性能稳定。
以下部分包含ZooKeeper管理员需要考虑的事项,以最大化这些假设成立的概率。其中一些是跨机器的考量因素,另一些则是您在部署中每台机器上都应考虑的事项。
跨机器需求
要使ZooKeeper服务保持活跃状态,必须有多数能够相互通信的非故障机器。对于一个包含N台服务器的ZooKeeper集群,如果N是奇数,该集群能够容忍最多N/2台服务器故障而不会丢失任何znode数据;如果N是偶数,该集群能够容忍最多N/2-1台服务器故障。
例如,如果我们有一个由3台服务器组成的ZooKeeper集群,该集群最多可以容忍1(3/2)台服务器故障。如果我们有一个由5台服务器组成的ZooKeeper集群,该集群最多可以容忍2(5/2)台服务器故障。如果是由6台服务器组成的ZooKeeper集群,该集群同样最多可以容忍2(6/2-1)台服务器故障而不会丢失数据,并能防止"脑裂"问题。
ZooKeeper集群通常由奇数台服务器组成。这是因为当服务器数量为偶数时,其容错能力与少一台服务器的集群相同(5节点集群和6节点集群都只能容忍2个节点故障),但集群却需要为多出的那台服务器维护额外的连接和数据传输。
为了最大程度地容忍故障,您应尽量确保机器故障相互独立。例如,如果大多数机器共享同一交换机,该交换机的故障可能导致关联故障并使服务中断。共享电源电路、冷却系统等同样适用此原则。
单机需求
如果ZooKeeper必须与其他应用程序竞争存储介质、CPU、网络或内存等资源,其性能将显著下降。ZooKeeper具有强大的持久性保证,这意味着它会在允许完成导致变更的操作之前,使用存储介质记录变更。因此您应该意识到这种依赖性,如果希望确保ZooKeeper操作不受存储介质影响,就需要格外注意。以下是您可以采取的一些措施来尽量减少此类性能下降:
- ZooKeeper的事务日志必须存放在专用设备上(仅使用独立分区是不够的)。ZooKeeper会顺序写入日志而无需寻址,若与其他进程共享日志设备可能导致寻址操作和资源争用,进而引发数秒级的延迟。
- 不要让ZooKeeper处于可能导致交换内存的情况。为了保证ZooKeeper能够及时响应,绝对不允许发生内存交换。因此,请确保分配给ZooKeeper的最大堆内存不超过其可用的物理内存容量。更多相关信息,请参阅下方的Things to Avoid。
资源调配
注意事项:ZooKeeper的优势与限制
管理
维护
ZooKeeper集群几乎不需要长期维护,但您必须注意以下几点:
正在进行的数据目录清理
ZooKeeper的数据目录包含特定服务集群存储的znode持久化副本文件,包括快照和事务日志文件。当znode发生变更时,这些变更会被追加到事务日志中。当日志增长到一定大小时,系统会将所有znode的当前状态快照写入文件系统,并创建新的事务日志文件用于后续事务。在快照过程中,ZooKeeper可能继续将新到达的事务追加到旧日志文件中。因此,某些比快照更新的事务可能会出现在快照前的最后一个事务日志中。
ZooKeeper服务器不会自动删除旧的快照和日志文件(默认配置下,参见下文autopurge设置),这是运维人员的职责。每个运行环境都不同,因此管理这些文件的需求可能因安装而异(例如备份需求)。
PurgeTxnLog工具实现了一个简单的保留策略,管理员可以使用该策略。API文档包含了调用约定(参数等)的详细信息。
在以下示例中,将保留最后
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功能设置滚动文件追加器。发布包tar中的示例配置文件conf/logback.xml提供了相关示例。
监控管理
您需要一个监督进程来管理每个ZooKeeper服务器进程(JVM)。ZK服务器被设计为"快速失败",这意味着当遇到无法恢复的错误时,它会立即关闭(进程退出)。由于ZooKeeper服务集群具有高度可靠性,即使单个服务器宕机,整个集群仍能保持活跃状态并继续处理请求。此外,由于集群具有"自我修复"能力,故障服务器在重启后将自动重新加入集群,无需任何人工干预。
使用像daemontools或SMF这样的监管进程(还有其他监管进程选项可供选择,具体使用哪种由您决定,这里只是两个示例)来管理您的ZooKeeper服务器,可以确保如果进程异常退出,它将自动重启并快速重新加入集群。
还建议配置ZooKeeper服务器进程,在发生OutOfMemoryError**错误时终止并转储其堆内存。这可以通过分别在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服务可以通过以下三种主要方式进行监控:
- 通过使用4 letter words来设置命令端口
- 使用 JMX
- 使用
zkServer.sh status命令
日志记录
ZooKeeper使用SLF4J 1.7版本作为其日志记录基础设施。默认情况下ZooKeeper附带LOGBack作为日志记录后端,但您可以选择使用任何其他受支持的日志记录框架。
ZooKeeper默认的logback.xml文件位于conf目录中。Logback要求logback.xml必须位于工作目录(运行ZooKeeper的目录)中,或者可以通过类路径访问。
有关SLF4J的更多信息,请参阅其手册。
有关Logback的更多信息,请参阅Logback网站。
故障排除
- 由于文件损坏导致服务器无法启动:当ZooKeeper服务器的事务日志出现文件损坏时,服务器可能无法读取数据库从而导致启动失败。此时会看到加载ZooKeeper数据库时抛出IOException异常。遇到这种情况时,请首先确保集群中其他服务器都正常运行。可以通过命令端口执行"stat"命令检查它们的状态。确认集群其他服务器都正常运行后,您可以清理故障服务器的数据库。删除datadir/version-2和datalogdir/version-2/目录下的所有文件,然后重启服务器。
配置参数
ZooKeeper的行为由ZooKeeper配置文件控制。该文件的设计使得只要磁盘布局相同,组成ZooKeeper服务器的所有服务器都可以使用完全相同的配置文件。如果服务器使用不同的配置文件,则必须注意确保所有不同配置文件中的服务器列表匹配。
注意
在3.5.0及更高版本中,部分参数应放置在动态配置文件中。如果这些参数被放置在静态配置文件中,ZooKeeper会自动将它们迁移到动态配置文件。更多信息请参阅Dynamic Reconfiguration。
最低配置
以下是配置文件中必须定义的最小配置关键词:
-
clientPort : 监听客户端连接的端口;即客户端尝试连接的端口。
-
secureClientPort : 用于监听SSL安全客户端连接的端口。clientPort指定明文连接的端口,而secureClientPort指定SSL连接的端口。同时指定两者可启用混合模式,省略任一则会禁用该模式。请注意,当用户配置zookeeper.serverCnxnFactory和zookeeper.clientCnxnSocket为Netty时,SSL功能将被启用。
-
observerMasterPort : 监听观察者连接的端口;即观察者尝试连接的端口。如果设置了该属性,服务器在跟随者模式下也会像领导者模式一样托管观察者连接,并在观察者模式下相应地尝试连接到任何投票节点。
-
dataDir : ZooKeeper存储内存数据库快照的位置,除非另有指定,否则也用于存储数据库更新的事务日志。
注意
请谨慎选择事务日志的存储位置。专用的事务日志设备是保持稳定高性能的关键。将日志放在繁忙的设备上会对性能产生不利影响。
- tickTime : ZooKeeper使用的基本时间单位,以毫秒计量的单次tick时长。它用于调节心跳和超时设置。例如,最小会话超时时间为两个tick。
高级配置
本节中的配置设置是可选的。您可以使用它们进一步微调ZooKeeper服务器的行为。其中一些也可以通过Java系统属性设置,通常形式为zookeeper.keyword。当可用时,具体的系统属性会在下方注明。
- dataLogDir : (无Java系统属性) 该选项将指示机器将事务日志写入dataLogDir而非dataDir。这允许使用专用的日志设备,并有助于避免日志记录与快照之间的竞争。
注意
拥有专用日志设备对吞吐量和稳定延迟有重大影响。强烈建议使用专用日志设备,并将dataLogDir设置为指向该设备上的目录,同时确保将dataDir指向不驻留在该设备上的目录。
- globalOutstandingLimit : (Java系统属性: zookeeper.globalOutstandingLimit.) 客户端提交请求的速度可能快于ZooKeeper处理的速度,特别是在客户端数量较多的情况下。为了防止ZooKeeper因排队请求而耗尽内存,ZooKeeper会对客户端进行限流,确保整个集群中未完成的请求不超过globalOutstandingLimit值,这个限制会被平均分配。默认限制为1,000,例如在3个成员的情况下,每个成员将拥有1000 / 2 = 500的独立限制。
-
preAllocSize : (Java系统属性: zookeeper.preAllocSize) 为了避免磁盘寻址,ZooKeeper会以preAllocSize千字节为块单位预分配事务日志文件空间。默认块大小为64M。调整块大小的一个原因是当快照更频繁时可以减少块大小。(另请参阅snapCount和snapSizeLimitInKb)。
-
snapCount : (Java系统属性: zookeeper.snapCount) ZooKeeper使用快照和事务日志(类似于预写日志)来记录其事务。在生成快照(并滚动事务日志)之前,事务日志中记录的事务数量由snapCount决定。为了防止仲裁组中的所有机器同时生成快照,当事务日志中的事务数量达到运行时生成的[snapCount/2+1, snapCount]范围内的随机值时,每个ZooKeeper服务器将生成一个快照。默认的snapCount值为100,000。
-
commitLogCount * : (Java 系统属性: zookeeper.commitLogCount) Zookeeper 维护一个内存中的最近提交请求列表,用于在追随者落后不多时快速同步。当您的快照较大(>100,000)时,这能提高同步性能。默认值为500,这是推荐的最小值。
-
snapSizeLimitInKb : (Java系统属性: zookeeper.snapSizeLimitInKb) ZooKeeper使用快照和事务日志(类似于预写日志)来记录其事务。在可以创建快照(并滚动事务日志)之前,事务日志中记录的事务集允许的总字节大小由snapSize决定。为了防止仲裁组中的所有机器同时创建快照,当事务日志中事务集的字节大小达到运行时生成的[snapSize/2+1, snapSize]范围内的随机值时,每个ZooKeeper服务器将创建快照。每个文件系统都有一个最小的标准文件大小,为了使此功能正常工作,选择的数值必须大于该值。默认的snapSizeLimitInKb为4,194,304(4GB)。非正值将禁用此功能。
-
txnLogSizeLimitInKb : (Java系统属性: zookeeper.txnLogSizeLimitInKb) 也可以通过txnLogSizeLimitInKb直接控制Zookeeper事务日志文件的大小。当使用事务日志进行同步时,过大的事务日志会导致追随者同步变慢。这是因为领导者需要扫描磁盘上相应的日志文件以找到开始同步的事务。默认情况下此功能是关闭的,此时只有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,但适用于获取子节点请求。可以通过指标response_packet_get_children_cache_hits和response_packet_get_children_cache_misses来根据工作负载调整此值。该功能默认启用,值为400,设置为0或负整数可关闭此功能。
-
autopurge.snapRetainCount : (无Java系统属性) 3.4.0新增: 启用时,ZooKeeper自动清理功能会保留最近的autopurge.snapRetainCount个快照及对应的交易日志,分别存放在dataDir和dataLogDir中,并删除其余文件。默认值为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.4/3.6.0版本不再支持3.5.3版本创建的TTL节点。但通过zookeeper.emulate353TTLNodes系统属性提供了变通方案。如果您在ZooKeeper 3.5.3中使用了TTL节点并需要保持兼容性,请将zookeeper.emulate353TTLNodes设为
true,同时设置zookeeper.extendedTypesEnabled。注意:由于该bug,服务器ID必须为127或更小。此外,支持的最大TTL值为1099511627775,比3.5.3允许的值(1152921504606846975)要小。 -
watchManagerName : (仅Java系统属性: zookeeper.watchManagerName) 3.6.0新增: 在ZOOKEEPER-1179中新增了优化版观察管理器WatchManagerOptimized,用于优化高频率观察场景下的内存开销。此配置用于定义使用哪种观察管理器。目前我们仅支持WatchManager和WatchManagerOptimized。
-
watcherCleanThreadsNum : (仅Java系统属性: zookeeper.watcherCleanThreadsNum) 3.6.0新增: 在ZOOKEEPER-1179中引入。新的观察者管理器WatchManagerOptimized会延迟清理失效的观察者,此配置用于决定WatcherCleaner中使用多少线程。更多线程通常意味着更高的清理吞吐量。默认值为2,即使在频繁且持续的会话关闭/重建场景下也足够使用。
-
watcherCleanThreshold : (仅Java系统属性: zookeeper.watcherCleanThreshold) 3.6.0新增: 在ZOOKEEPER-1179中引入。新的观察者管理器WatchManagerOptimized会延迟清理失效的观察者,清理过程相对较重,批量处理可以降低成本并提高性能。此设置用于决定批量大小。默认值为1000,如果没有内存或清理速度问题,我们不需要更改它。
-
watcherCleanIntervalInSeconds : (仅Java系统属性: zookeeper.watcherCleanIntervalInSeconds) 3.6.0新增: 在ZOOKEEPER-1179中引入。新的观察者管理器WatchManagerOptimized会惰性清理失效观察者,清理过程相对较重,批量处理可以降低成本并提升性能。除了watcherCleanThreshold之外,此设置用于在一定时间后清理失效观察者,即使失效观察者数量未达到watcherCleanThreshold阈值,这样我们就不会让失效观察者留存过长时间。默认设置为10分钟,通常无需修改。
-
maxInProcessingDeadWatchers : (仅Java系统属性: zookeeper.maxInProcessingDeadWatchers) 3.6.0新增: 在ZOOKEEPER-1179中添加 用于控制WatcherCleaner中可以积压的最大数量,当达到此数值时,会减缓将失效监视器添加到WatcherCleaner的速度,进而减缓添加和关闭监视器的速度,从而避免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)采用退避策略。
-
fastleader.maxNotificationInterval : (Java系统属性: zookeeper.fastleader.maxNotificationInterval) 领导选举中两次连续通知检查之间的时间上限。此间隔决定了节点等待检查选举投票集的时间,并影响选举能够多快完成。对于长时间选举,该间隔会从配置的最小值(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服务器套接字的连接请求队列长度。该参数控制将被排队等待ZooKeeper服务器处理的请求数量。超过此长度的连接将收到网络超时(30秒),可能导致ZooKeeper会话过期问题。默认情况下,该值未设置(
-1),在Linux系统上会使用50的队列长度。此值必须为正数。 -
serverCnxnFactory : (Java系统属性: zookeeper.serverCnxnFactory) 指定ServerCnxnFactory实现。要使用基于TLS的服务器通信,应将其设置为
NettyServerCnxnFactory。默认为NIOServerCnxnFactory。 -
flushDelay : (Java系统属性: zookeeper.flushDelay) 提交日志刷新的延迟时间(毫秒)。不影响maxBatchSize定义的限制。默认禁用(值为0)。对于写入率高的集群,设置为10-20毫秒可能会提高吞吐量。
-
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检查。默认值为"false"。
-
maxConcurrentSnapSyncs : (Java系统属性: zookeeper.leader.maxConcurrentSnapSyncs) 领导者或跟随者可以同时处理的最大快照同步数量。默认值为10。
-
maxConcurrentDiffSyncs : (Java系统属性: zookeeper.leader.maxConcurrentDiffSyncs) 领导者或跟随者可以同时处理的最大差异同步数量。默认值为100。
-
digest.enabled : (仅Java系统属性: zookeeper.digest.enabled) 3.6.0新增: 摘要功能用于在从磁盘加载数据库、追赶和跟随领导者时检测ZooKeeper内部的数据不一致性,它基于adHash论文对DataTree进行增量哈希检查。
https://cseweb.ucsd.edu/~daniele/papers/IncHash.pdf思路很简单,DataTree的哈希值会根据数据集的变化进行增量更新。当领导者准备事务时,它会根据公式预先计算树结构因变更而产生的新哈希值:
current_hash = current_hash + hash(new node data) - hash(old node data)如果是创建新节点,则hash(旧节点数据)将为0;如果是删除节点操作,则hash(新节点数据)将为0。
这个哈希值将与每个事务相关联,表示将该事务应用到数据树后期望的哈希值,它会随原始提案一起发送给跟随者。学习者将在事务应用到数据树后,将实际哈希值与事务中的哈希值进行比较,如果不一致则报告不匹配。
这些摘要值也会与每个事务和磁盘上的快照一起持久化保存,因此当服务器重启并从磁盘加载数据时,它会进行比较并查看是否存在哈希不匹配的情况,这将有助于检测磁盘上的数据丢失问题。
对于实际的哈希函数,我们在内部使用的是CRC,它并非无冲突的哈希函数,但与无冲突哈希相比效率更高,且碰撞概率极低,完全能满足我们当前的需求。
该功能具有向后和向前兼容性,因此可以安全地进行滚动升级、降级、启用以及后续禁用,而不会出现任何兼容性问题。以下是已覆盖并测试过的场景:
- 当领导者运行新代码而跟随者运行旧代码时,摘要信息会被附加到每个事务的末尾,跟随者只会读取头部和事务数据,事务中的摘要值将被忽略。这不会影响跟随者读取和处理下一个事务。
- 当领导者运行旧代码而跟随者运行新代码时,摘要不会随事务一起发送。当跟随者尝试读取摘要时,会抛出EOF异常,该异常会被捕获并以摘要值设为null的方式优雅处理。
- 当使用新代码加载旧快照时,尝试读取不存在的摘要值时会抛出IOException异常,该异常将被捕获并将摘要设置为null,这意味着在加载此快照时不会比较摘要,这在滚动升级期间是预期会发生的情况
- 使用旧代码加载新快照时,在反序列化数据树后会成功完成,快照文件末尾的摘要值将被忽略
- 带有标志变更的滚动重启场景与上述第1和第2种场景类似:如果领导者启用但跟随者未启用,摘要值将被忽略,且跟随者在运行时不会比较摘要;如果领导者禁用但跟随者启用,跟随者将获得EOF异常,该异常会被优雅处理。
注意:当前的摘要计算排除了/zookeeper下的节点,这是由于/zookeeper/quota状态节点可能存在不一致性,我们可以在该问题修复后将其包含进来。
默认情况下,此功能处于启用状态,设置为"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之前版本)升级时,这些版本可能只存在事务日志文件而没有快照文件的情况。如果在升级过程中设置了该值,我们建议在升级完成后将该值改回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握手过多导致握手超时引发的群体效应。将其设置为类似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新增: 启用时,学习者将异步关闭仲裁套接字。这对于TLS连接非常有用,因为关闭套接字可能需要很长时间,阻塞关闭过程,可能延迟新领导者选举,并使仲裁不可用。异步关闭套接字可以避免因套接字关闭时间长而阻塞关闭过程,并且可以在套接字关闭时启动新的领导者选举。默认值为false。
-
leader.closeSocketAsync (Java系统属性: zookeeper.leader.closeSocketAsync) (Java系统属性: leader.closeSocketAsync)(为向后兼容而添加) 3.7.0新增: 启用时,leader将异步关闭仲裁socket。这对于TLS连接特别有用,因为关闭socket可能需要较长时间。如果在ping()中由于SyncLimitCheck失败而发起与follower的断开连接,那么长时间的socket关闭会阻塞向其他follower发送ping。其他follower收不到ping就不会向leader发送会话信息,从而导致会话过期。将此标志设为true可确保定期发送ping。默认值为false。
-
learner.asyncSending (Java系统属性: zookeeper.learner.asyncSending) (Java系统属性: learner.asyncSending)(为向后兼容而添加) 3.7.0新增: 在Learner中,数据包的发送和接收原本是在临界区同步进行的。不合时宜的网络问题可能导致追随者挂起(参见ZOOKEEPER-3575和ZOOKEEPER-4074)。新设计将Learner中的数据包发送移至单独线程并异步发送数据包。通过此参数(learner.asyncSending)可启用新设计。默认值为false。
-
forward_learner_requests_to_commit_processor_disabled (Java系统属性: zookeeper.forward_learner_requests_to_commit_processor_disabled) 当设置此属性时,来自学习者的请求将不会被加入CommitProcessor队列,这将有助于节省领导者上的资源和GC时间。
默认值为false。
-
serializeLastProcessedZxid.enabled (Java系统属性: zookeeper.serializeLastProcessedZxid.enabled) 3.9.0新增: 如果启用,ZooKeeper会在创建快照时序列化lastProcessedZxid,并在恢复时反序列化。默认为true。需要通过管理服务器命令执行快照和恢复操作时必须启用此选项,因为此时没有快照文件名可用于提取lastProcessedZxid。
该功能具有向后和向前兼容性。以下是不同的场景。
-
由服务器内部触发的快照。当使用新代码加载旧快照时,尝试读取不存在的lastProcessedZxid值时会抛出EOFException,该异常将被捕获。lastProcessedZxid将通过快照文件名进行设置。
b. 当使用旧代码加载新快照时,在反序列化摘要值后会成功完成,快照文件末尾的lastProcessedZxid将被忽略。lastProcessedZxid将使用快照文件名来设置。
- 领导者与跟随者之间的同步 在旧代码和新代码中,lastProcessedZxid都不会被领导者序列化并由跟随者反序列化。它将被设置为通过QuorumPacket从领导者发送的lastProcessedZxid。
-
通过管理服务器API触发的快照功能 需要启用特性标志才能使快照命令生效。
集群选项
本节中的选项专为服务器集群设计——即在部署服务器集群时使用。
- electionAlg : (无Java系统属性) 使用的选举算法实现。值为"1"对应基于UDP的无认证快速领导者选举版本,"2"对应基于UDP的认证快速领导者选举版本,"3"对应基于TCP的快速领导者选举版本。从3.2.0版本开始算法3成为默认选项,而早期版本(3.0.0和3.1.0)使用的是算法1和2。
注意
领导者选举实现1和2已在3.4.0版本中弃用。自3.6.0版本起仅保留FastLeaderElection,如需升级必须关闭所有服务器并使用electionAlg=3(或从配置文件中移除该行)重新启动。
- maxTimeToWaitForEpoch : (Java 系统属性: zookeeper.leader.maxTimeToWaitForEpoch) 3.6.0 新增: 当激活领导者时等待投票者发送epoch的最大时间。如果领导者从某个投票者收到LOOKING通知,且在maxTimeToWaitForEpoch时间内未收到大多数节点的epoch数据包,它将转为LOOKING状态并重新选举领导者。该参数可用于减少仲裁或服务器不可用时间,可以设置为远小于initLimit * tickTime的值。在跨数据中心环境中,可设置为类似2秒的值。
-
initLimit : (无Java系统属性) 以滴答时间为单位(参见tickTime),允许追随者连接并与领导者同步的时间。如果ZooKeeper管理的数据量较大,可根据需要增加此值。
-
connectToLearnerMasterLimit : (Java系统属性: zookeeper.connectToLearnerMasterLimit) 允许follower在leader选举后连接到leader的时间长度,以ticks为单位(参见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服务器自身拥有的列表一致。其中有两个端口号nnnnn,第一个用于追随者连接领导者,第二个用于领导者选举。如果要在单台机器上测试多个服务器,可以为每个服务器使用不同的端口。
从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注意
启用此功能后,仲裁协议(ZooKeeper服务器间协议)将会改变。用户不会注意到这一点,当任何人使用新配置启动ZooKeeper集群时,一切都会正常工作。但是,如果旧的ZooKeeper集群不支持multiAddress功能(以及新的仲裁协议),则无法在滚动升级过程中启用此功能并指定多个地址。如果您需要此功能,但还需要从早于3.6.0的ZooKeeper集群执行滚动升级,那么您首先需要在不启用MultiAddress功能的情况下进行滚动升级,然后再使用新配置进行单独的滚动重启,其中multiAddress.enabled设置为true并提供了多个地址。
- syncLimit : (无Java系统属性) 允许追随者与ZooKeeper同步的时间长度,以滴答单位计(参见tickTime)。如果追随者落后领导者太多,它们将被丢弃。
-
group.x=nnnnn[:nnnnn] : (无Java系统属性) 启用分层式仲裁结构。"x"代表组标识符,等号后的数字对应服务器标识符。赋值左侧是以冒号分隔的服务器标识符列表。请注意各组必须互不相交,且所有组的并集必须构成ZooKeeper集群。示例可查看此处
-
weight.x=nnnnn : (无Java系统属性) 与"group"配合使用时,用于在形成法定人数时为服务器分配权重。该值对应服务器在投票时的权重。ZooKeeper中有几个部分需要投票,例如领导者选举和原子广播协议。默认情况下,服务器的权重为1。如果配置定义了组但未定义权重,则将为所有服务器分配值1。您可以在此处找到一个示例
-
cnxTimeout : (Java 系统属性: zookeeper.cnxTimeout) 设置用于领导者选举通知的连接打开超时值。仅在使用 electionAlg 3 时适用。
注意
默认值为 5 秒。
- quorumCnxnTimeoutMs : (Java系统属性: zookeeper.quorumCnxnTimeoutMs) 设置领导者选举通知连接的读取超时值。仅在使用electionAlg 3时适用。
注意
默认值为-1,此时将使用syncLimit * tickTime作为超时时间。
- standaloneEnabled : (无Java系统属性) 3.5.0新增: 当设置为false时,单个服务器可以在复制模式下启动,独立参与者可以与观察者一起运行,集群可以重新配置缩减到单个节点,也可以从单个节点扩展。默认值为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,将导致不一致行为,具体取决于哪个服务器被选举为领导者。如果领导者设置为"reconfigEnabled=true",则集群将启用重新配置功能;如果领导者设置为"reconfigEnabled=false",则集群将禁用该功能。因此建议在整个集群的所有服务器上保持"reconfigEnabled"值的一致性。
-
4lw.commands.whitelist : (Java系统属性: zookeeper.4lw.commands.whitelist) 3.5.3版本新增: 用户希望使用的四字命令列表,以逗号分隔。有效的四字命令必须包含在此列表中,否则ZooKeeper服务器将不会启用该命令。默认情况下,白名单仅包含zkServer.sh使用的"srvr"命令。其余四字命令默认禁用:尝试使用它们将获得响应"....未被执行,因为它不在白名单中。" 以下是一个配置示例,启用stat、ruok、conf和isro命令,同时禁用其他四字命令:
4lw.commands.whitelist=stat, ruok, conf, isro
如果您确实需要默认启用所有四字母命令,可以使用星号选项,这样就不必在列表中逐一包含每个命令。例如,这将启用所有四字母命令:
4lw.commands.whitelist=*
-
tcpKeepAlive : (Java系统属性: zookeeper.tcpKeepAlive) 3.5.4版本新增: 将此设置为true会在仲裁成员用于执行选举的套接字上设置TCP keepAlive标志。当存在可能断开连接的网络基础设施时,这将允许仲裁成员之间的连接保持活动状态。某些NAT和防火墙可能会终止或丢失长时间运行或空闲连接的状态。启用此选项依赖于操作系统级别的设置才能正常工作,有关更多信息,请查看您操作系统关于TCP keepalive的选项。默认为false。
-
clientTcpKeepAlive : (Java系统属性: zookeeper.clientTcpKeepAlive) 3.6.1新增: 将此设置为true会在客户端套接字上设置TCP keepAlive标志。某些有问题的网络基础设施可能会丢失客户端关闭时发送的FIN数据包。这些从未关闭的客户端套接字会导致操作系统资源泄漏。启用此选项可通过空闲检查终止这些僵尸套接字。启用此选项依赖于操作系统级别的设置才能正常工作,有关TCP keepalive的更多信息,请查看您操作系统的相关选项。默认为false。请注意它与tcpKeepAlive的区别。它应用于客户端套接字,而tcpKeepAlive用于仲裁成员使用的套接字。目前此选项仅在默认使用
NIOServerCnxnFactory时可用。 -
electionPortBindRetry : (仅Java系统属性: zookeeper.electionPortBindRetry) 当Zookeeper服务器无法绑定领导者选举端口时,该属性设置最大重试次数。此类错误可能是暂时且可恢复的,如ZOOKEEPER-3320中描述的DNS问题,也可能是不可重试的,如端口已被占用。对于暂时性错误,此属性可以提高Zookeeper服务器的可用性并帮助其自我恢复。默认值为3。在容器环境(特别是Kubernetes)中,应增大此值或设为0(无限重试)以解决与DNS名称解析相关的问题。
-
observer.reconnectDelayMs : (Java 系统属性: zookeeper.observer.reconnectDelayMs) 当观察者与领导者失去连接时,它会等待指定的时间值后再尝试重新连接领导者,这样整个观察者集群不会立即尝试进行领导者选举和重新连接。默认值为 0 毫秒。
-
observer.election.DelayMs : (Java 系统属性: zookeeper.observer.election.DelayMs) 延迟观察者参与领导者选举的时间,以防止在选举过程中给投票节点带来意外的额外负载。默认值为200毫秒。
-
localSessionsEnabled 和 localSessionsUpgradingEnabled : 3.5版本新增: 可选值为true或false。默认值为false。通过设置localSessionsEnabled=true来启用本地会话功能。启用localSessionsUpgradingEnabled可以根据需要(例如创建临时节点)自动将本地会话升级为全局会话,这仅在启用localSessionsEnabled时才有意义。
加密、认证与授权选项
本节中的选项允许控制由服务执行的加密/认证/授权操作。
除了本页面外,您还可以在程序员指南中找到有关客户端配置的有用信息。ZooKeeper Wiki还包含关于ZooKeeper SSL支持和ZooKeeper的SASL认证的有用页面。
-
DigestAuthenticationProvider.enabled : (Java系统属性: zookeeper.DigestAuthenticationProvider.enabled) 3.7版本新增: 决定是否启用
digest认证提供程序。为了向后兼容,默认值为true,但如果未使用该提供程序,建议禁用它,因为这可能导致审计日志中出现误导性条目(参见ZOOKEEPER-3979) -
DigestAuthenticationProvider.superDigest : (Java系统属性: zookeeper.DigestAuthenticationProvider.superDigest) 默认情况下此功能是禁用的 3.2版本新增: 允许ZooKeeper集群管理员以"超级"用户身份访问znode层级结构。特别地,对于认证为超级用户的请求不会进行ACL检查。可以使用org.apache.zookeeper.server.auth.DigestAuthenticationProvider来生成superDigest,调用时传入"super:
"作为参数。在启动集群中的每个服务器时,将生成的"super:"作为系统属性值提供。当向ZooKeeper服务器认证时(从ZooKeeper客户端),传递"digest"方案和"super: "认证数据。请注意摘要认证会以明文形式将认证数据传输到服务器,建议仅在本地主机(不通过网络)或加密连接上使用此认证方法。 -
DigestAuthenticationProvider.digestAlg : (Java系统属性: zookeeper.DigestAuthenticationProvider.digestAlg) 3.7.0新增: 设置ACL摘要算法。默认值为:
SHA1,由于安全问题将在未来弃用。请在所有服务器上将此属性设置为相同的值。-
如何支持其他更多算法?
-
修改位于
$JAVA_HOME/jre/lib/security/java.security下的java.security配置文件,指定:security.provider.。= 例如: set zookeeper.DigestAuthenticationProvider.digestAlg=RipeMD160 security.provider.3=org.bouncycastle.jce.provider.BouncyCastleProvider -
将jar文件复制到
$JAVA_HOME/jre/lib/ext/目录下。例如: 将bcprov-jdk18on-1.60.jar复制到$JAVA_HOME/jre/lib/ext/目录下
-
-
如何从一种摘要算法迁移到另一种?
-
- 迁移到新算法时重新生成
superDigest。
- 迁移到新算法时重新生成
-
SetAcl用于已使用旧算法摘要认证的znode节点。
-
-
-
IPAuthenticationProvider.usexforwardedfor : (Java 系统属性: 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系统属性: zookeeper.X509AuthenticationProvider.superUser) 该SSL认证方式允许ZooKeeper集群管理员以"超级"用户身份访问znode层级结构。当此参数设置为X500主体名称时,只有通过认证且拥有该主体的客户端才能绕过ACL检查,并对所有znode拥有完全权限。
-
zookeeper.superUser : (Java系统属性: zookeeper.superUser) 类似于 zookeeper.X509AuthenticationProvider.superUser,但适用于基于SASL的登录。它存储了一个可以以"超级"用户身份访问znode层次结构的用户名。您可以使用zookeeper.superUser.[后缀]的表示法指定多个SASL超级用户,例如:
zookeeper.superUser.1=...。 -
ssl.authProvider : (Java系统属性: 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系统属性: 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系统属性: zookeeper.sslQuorum) 3.5.5版本新增: 启用加密的仲裁通信。默认值为
false。启用此功能时,请同时考虑启用leader.closeSocketAsync和learner.closeSocketAsync,以避免在关闭SSL连接时可能出现的长时间套接字关闭问题。 -
ssl.keyStore.location 和 ssl.keyStore.password 以及 ssl.quorum.keyStore.location 和 ssl.quorum.keyStore.password : (Java 系统属性: zookeeper.ssl.keyStore.location 和 zookeeper.ssl.keyStore.password 以及 zookeeper.ssl.quorum.keyStore.location 和 zookeeper.ssl.quorum.keyStore.password) 3.5.5 版本新增: 指定包含用于客户端和仲裁 TLS 连接的本地凭证的 Java 密钥库文件路径,以及用于解锁该文件的密码。
-
ssl.keyStore.passwordPath 和 ssl.quorum.keyStore.passwordPath : (Java 系统属性: zookeeper.ssl.keyStore.passwordPath 和 zookeeper.ssl.quorum.keyStore.passwordPath) 3.8.0 新增: 指定包含密钥库密码的文件路径。从文件中读取密码的优先级高于显式密码属性。
-
ssl.keyStore.type 和 ssl.quorum.keyStore.type : (Java系统属性: zookeeper.ssl.keyStore.type 和 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 和 ssl.trustStore.password 以及 ssl.quorum.trustStore.location 和 ssl.quorum.trustStore.password : (Java系统属性: zookeeper.ssl.trustStore.location 和 zookeeper.ssl.trustStore.password 以及 zookeeper.ssl.quorum.trustStore.location 和 zookeeper.ssl.quorum.trustStore.password) 3.5.5版本新增: 指定Java信任库文件路径,该信任库包含用于客户端和仲裁TLS连接的远程凭证,以及解锁该文件的密码。
-
ssl.trustStore.passwordPath 和 ssl.quorum.trustStore.passwordPath : (Java 系统属性: zookeeper.ssl.trustStore.passwordPath 和 zookeeper.ssl.quorum.trustStore.passwordPath) 3.8.0 新增: 指定包含信任库密码的文件路径。从文件中读取密码优先于显式密码属性。
-
ssl.trustStore.type 和 ssl.quorum.trustStore.type : (Java系统属性: zookeeper.ssl.trustStore.type 和 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 和 ssl.quorum.protocol : (Java系统属性: zookeeper.ssl.protocol 和 zookeeper.ssl.quorum.protocol) 3.5.5版本新增: 指定在客户端和仲裁TLS协商中使用的协议。默认值: 根据所使用的Java运行时版本,可能是TLSv1.3或TLSv1.2。
-
ssl.enabledProtocols 和 ssl.quorum.enabledProtocols : (Java 系统属性: zookeeper.ssl.enabledProtocols 和 zookeeper.ssl.quorum.enabledProtocols) 3.5.5 版本新增: 指定客户端和仲裁 TLS 协商中启用的协议。默认值: 如果
protocol属性值为 TLSv1.3 则为 TLSv1.3, TLSv1.2。如果protocol为 TLSv1.2 则为 TLSv1.2。 -
ssl.ciphersuites 和 ssl.quorum.ciphersuites : (Java系统属性: zookeeper.ssl.ciphersuites 和 zookeeper.ssl.quorum.ciphersuites) 3.5.5版本新增: 指定在客户端和仲裁TLS协商中启用的加密套件。默认值: 启用的加密套件取决于所使用的Java运行时版本。
-
ssl.context.supplier.class 和 ssl.quorum.context.supplier.class : (Java系统属性: zookeeper.ssl.context.supplier.class 和 zookeeper.ssl.quorum.context.supplier.class) 3.5.5版本新增: 指定用于在客户端和仲裁SSL通信中创建SSL上下文的类。这允许您使用自定义SSL上下文并实现以下场景:
- 使用硬件密钥库,通过PKCS11或类似方式加载。
- 您无法访问软件密钥库,但可以从其容器中检索已构建的SSLContext。默认值:null
-
ssl.hostnameVerification 和 ssl.quorum.hostnameVerification : (Java系统属性: zookeeper.ssl.hostnameVerification 和 zookeeper.ssl.quorum.hostnameVerification) 3.5.5版本新增: 指定在客户端和仲裁TLS协商过程中是否启用主机名验证。仅建议在测试时禁用此功能。默认值: true
-
ssl.crl 和 ssl.quorum.crl : (Java系统属性: zookeeper.ssl.crl 和 zookeeper.ssl.quorum.crl) 3.5.5版本新增: 指定在客户端和仲裁TLS协议中是否启用证书吊销列表。默认值: false
-
ssl.ocsp 和 ssl.quorum.ocsp : (Java系统属性: zookeeper.ssl.ocsp 和 zookeeper.ssl.quorum.ocsp) 3.5.5版本新增: 指定在客户端和仲裁TLS协议中是否启用在线证书状态协议。默认值: false
-
ssl.clientAuth 和 ssl.quorum.clientAuth : (Java系统属性: zookeeper.ssl.clientAuth 和 zookeeper.ssl.quorum.clientAuth) 3.5.5版本新增,但在3.5.7之前存在缺陷: 用于指定客户端SSL连接的身份验证选项。有效值为
- "none": 服务器不会要求客户端认证
- "want": 服务器将"请求"客户端认证
- "need": 服务器将"要求"客户端认证
默认值: "need"
-
ssl.handshakeDetectionTimeoutMillis 和 ssl.quorum.handshakeDetectionTimeoutMillis : (Java系统属性: zookeeper.ssl.handshakeDetectionTimeoutMillis 和 zookeeper.ssl.quorum.handshakeDetectionTimeoutMillis) 3.5.5版本新增: 待定
-
ssl.sslProvider : (Java系统属性: zookeeper.ssl.sslProvider) 3.9.0新增: 当启用TLS时,允许在客户端-服务器通信中选择SSL提供程序。ZooKeeper 3.9.0版本中新增了Netty-tcnative原生库,使我们能够在支持的平台上使用像OpenSSL这样的原生SSL库。具体可用选项请参阅Netty-tcnative文档。默认值为"JDK"。
-
sslQuorumReloadCertFiles : (无Java系统属性) 3.5.5, 3.6.0版本新增: 允许在文件系统中的证书变更时重新加载Quorum SSL密钥库和信任库,而无需重启ZK进程。默认值: false
-
client.certReload : (Java系统属性: zookeeper.client.certReload) 3.7.2、3.8.1、3.9.0版本新增: 当文件系统中的证书变更时,允许客户端SSL密钥库和信任库重新加载,而无需重启ZK进程。默认值: false
-
client.portUnification: (Java系统属性: zookeeper.client.portUnification) 指定客户端端口应接受SSL连接(使用与安全客户端端口相同的配置)。默认值: false
-
authProvider: (Java系统属性: zookeeper.authProvider) 您可以为ZooKeeper指定多个认证提供者类。通常您会使用此参数来指定SASL认证提供者,例如:
authProvider.1=org.apache.zookeeper.server.auth.SASLAuthenticationProvider -
kerberos.removeHostFromPrincipal (Java系统属性: zookeeper.kerberos.removeHostFromPrincipal) 您可以指示ZooKeeper在认证过程中从客户端主体名称中移除主机名。(例如,zk/myhost@EXAMPLE.COM客户端主体将在ZooKeeper中被认证为zk@EXAMPLE.COM) 默认值: false
-
kerberos.removeRealmFromPrincipal (Java系统属性: zookeeper.kerberos.removeRealmFromPrincipal) 您可以指示ZooKeeper在认证过程中从客户端主体名称中移除realm部分。(例如zk/myhost@EXAMPLE.COM客户端主体在ZooKeeper中将被认证为zk/myhost) 默认值: false
-
kerberos.canonicalizeHostNames (Java系统属性: zookeeper.kerberos.canonicalizeHostNames) 3.7.0新增: 指示ZooKeeper对从server.x行提取的服务器主机名进行规范化处理。这允许在配置文件中使用例如
CNAME记录来引用服务器,同时仍能在仲裁成员之间启用SASL Kerberos认证。它本质上相当于客户端的zookeeper.sasl.client.canonicalize.hostname属性的仲裁版本。为了向后兼容,默认值为false。 -
multiAddress.enabled : (Java系统属性: zookeeper.multiAddress.enabled) 3.6.0新增: 从ZooKeeper 3.6.0开始,您还可以为每个ZooKeeper服务器实例指定多个地址(当集群中可以使用多个物理网络接口并行时,这可以提高可用性)。将此参数设置为true将启用此功能。请注意,如果旧ZooKeeper集群的版本早于3.6.0,则无法在滚动升级期间启用此功能。默认值为false。
-
multiAddress.reachabilityCheckTimeoutMs : (Java系统属性: zookeeper.multiAddress.reachabilityCheckTimeoutMs) 3.6.0新增: 从ZooKeeper 3.6.0开始,您还可以为每个ZooKeeper服务器实例指定多个地址(当集群中可以使用多个物理网络接口并行工作时,这可以提高可用性)。ZooKeeper将执行ICMP ECHO请求或尝试在目标主机的端口7(Echo)上建立TCP连接,以查找可访问的地址。这仅在您在配置中提供多个地址时才会发生。在此属性中,您可以设置可达性检查的超时时间(毫秒)。检查会针对不同地址并行进行,因此您在此处设置的超时时间是检查所有地址可达性所需的最长时间。默认值为1000。
除非您通过设置multiAddress.enabled=true启用多地址功能,否则此参数无效。
-
fips-mode : (Java 系统属性: zookeeper.fips-mode) 3.8.2 新增: 在 ZooKeeper 中启用 FIPS 兼容模式。如果启用,用于主机名验证的自定义信任管理器 (
ZKTrustManager) 将被禁用以符合 FIPS 要求。因此,Quorum 协议中将无法使用主机名验证,但仍可在客户端-服务器通信中设置。默认值: true (3.9.0+), false (3.8.x)
实验性选项/功能
目前被视为实验性的新功能。
-
只读模式服务器 : (Java系统属性: readonlymode.enabled) 3.4.0新增: 将此值设为true可启用只读模式服务器支持(默认禁用)。ROM允许请求ROM支持的客户端会话连接到服务器,即使服务器可能已与仲裁集群分区。在此模式下,ROM客户端仍可从ZK服务读取值,但无法写入值或查看其他客户端的更改。详情请参阅ZOOKEEPER-784。
-
zookeeper.follower.skipLearnerRequestToNextProcessor : (Java系统属性: zookeeper.follower.skipLearnerRequestToNextProcessor) 当我们的集群中存在通过ObserverMaster连接的观察者时,启用此标志可能有助于减轻Observer Master的内存压力。如果您的集群没有任何观察者,或者它们未与ObserverMaster连接,或者您的观察者不进行大量写入操作,那么使用此标志将不会有帮助。目前此变更受标志保护,以便我们能够更可靠地评估内存收益。长远来看,我们可能会移除该标志并将其行为设为默认代码路径。
不安全选项
以下选项可能很有用,但使用时请务必谨慎。每个选项的风险说明会随变量功能的解释一并提供。
-
forceSync : (Java 系统属性: zookeeper.forceSync) 要求在完成更新处理前必须将更新同步到事务日志的存储介质。如果此选项设置为否,ZooKeeper将不要求将更新同步到存储介质。
-
jute.maxbuffer : (Java系统属性:jute.maxbuffer).
- 此选项只能作为Java系统属性设置。它没有zookeeper前缀。它指定了znode中可以存储的数据的最大大小。单位为:字节。默认值为0xfffff(1048575)字节,即略小于1M。
- 如果更改此选项,必须在所有服务器和客户端上设置系统属性,否则会出现问题。
- 当客户端的jute.maxbuffer大于服务器端时,如果客户端尝试写入超过服务器端jute.maxbuffer限制的数据,服务器端将出现java.io.IOException: Len error错误
- 当客户端的jute.maxbuffer小于服务端时,若客户端尝试读取超过其jute.maxbuffer限制的数据,客户端将收到java.io.IOException: 不合理长度或数据包长度超出范围!错误
- 这实际上是一个健全性检查。ZooKeeper设计用于存储大小在千字节级别的数据。在生产环境中,不建议增加此属性值超过默认值,原因如下:
- 大型znode会导致不必要的延迟峰值,降低吞吐量
- 大型znode会导致领导者与跟随者之间的同步时间不可预测且无法收敛(有时会超时),导致仲裁不稳定
-
jute.maxbuffer.extrasize: (Java系统属性: zookeeper.jute.maxbuffer.extrasize) 3.5.7新增: 在处理客户端请求时,ZooKeeper服务器会在将请求持久化为事务之前向请求中添加一些额外信息。早期这个额外信息的大小固定为1024字节。对于许多场景,特别是当jute.maxbuffer值超过1MB且请求类型为multi时,这个固定大小是不够的。为了处理所有场景,额外信息的大小从1024字节增加到与jute.maxbuffer相同的大小,并且可以通过jute.maxbuffer.extrasize进行配置。通常不需要配置此属性,因为默认值是最优值。
-
skipACL : (Java系统属性: zookeeper.skipACL) 跳过ACL检查。这将提高吞吐量,但会向所有人开放对数据树的完全访问权限。
-
quorumListenOnAllIPs : 当设置为true时,ZooKeeper服务器将在所有可用IP地址上监听来自其对等节点的连接,而不仅限于配置文件中服务器列表配置的地址。这会影响处理ZAB协议和快速领导者选举协议的连接。默认值为false。
-
multiAddress.reachabilityCheckEnabled : (Java 系统属性: zookeeper.multiAddress.reachabilityCheckEnabled) 3.6.0 新增: 从 ZooKeeper 3.6.0 开始,您还可以为每个 ZooKeeper 服务器实例指定多个地址(当集群中可并行使用多个物理网络接口时,这可以提高可用性)。ZooKeeper 将执行 ICMP ECHO 请求或尝试在目标主机的端口 7(Echo)上建立 TCP 连接,以查找可达地址。仅当您在配置中提供多个地址时才会发生这种情况。如果您触发了某些 ICMP 速率限制(例如在 macOS 上),当您尝试在一台机器上启动大型(例如 11 个以上)集群成员进行测试时,可达性检查可能会失败。
默认值为 true。通过将此参数设置为 'false',您可以禁用可达性检查。请注意,禁用可达性检查将导致集群在网络问题期间无法正确重新配置,因此建议仅在测试期间禁用。
除非您通过设置 multiAddress.enabled=true 启用多地址功能,否则此参数无效。
禁用数据目录自动创建
3.5版本新增:ZooKeeper服务器的默认行为是:如果启动时配置文件中指定的数据目录不存在,则会自动创建该目录。在某些情况下,这可能带来不便甚至危险。例如,正在运行的服务器进行了配置变更,其中dataDir参数被意外修改。当ZooKeeper服务器重启时,它将创建这个不存在的目录并开始提供服务——但此时znode命名空间是空的。这种情况可能导致实际的"脑裂"问题(即数据同时存在于新的无效目录和原始有效数据存储中)。因此最好能提供关闭这种自动创建行为的选项。一般来说生产环境应该禁用此功能,但遗憾的是目前无法更改默认的传统行为,因此需要根据具体情况处理。这需要由用户和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'命令)删除了数据目录,这种行为可能很危险,因为该服务器可能会帮助选举出一个缺失事务的领导者。启用数据库存在验证后,当未找到数据树时启动行为将改变:服务器会作为非投票参与者加入集群,直到能够与领导者同步并获取最新的集群数据版本。若要表示预期为空数据树(创建新集群),用户应在'myid'文件所在目录放置一个'initialize'文件。该文件将在服务器启动时被检测并删除。
当直接从类文件运行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) 在处理提交请求前,从队列请求中处理的最大读取数量。如果值小于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节点的最大数量。这可以防止容器删除期间的蜂拥现象。默认值为"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"时,将启用消息追踪器来跟踪和记录消息。默认值为"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摘要指标的worker线程数量。默认值为1。如果数值小于1,将使用主线程。
-
metricsProvider.maxQueueSize : 3.7.1版本新增: Prometheus摘要指标报告任务的最大队列大小。默认值为1000000。
-
metricsProvider.workerShutdownTimeoutMs : 3.7.1版本新增: Prometheus工作线程关闭的超时时间(毫秒)。默认值为1000毫秒。
使用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未被执行"。返回"imok"并不一定表示服务器已加入仲裁集群,仅表明服务器进程处于活动状态并绑定了指定的客户端端口。如需获取仲裁状态及客户端连接详情,请使用"stat"命令。 -
srst : 重置服务器统计信息。
-
srvr : 3.3.0版本新增: 列出服务器的完整详细信息。
-
stat : 列出服务器及已连接客户端的简要详情。
-
wchs : 3.3.0版本新增: 列出服务器上监视器的简要信息。
-
wchc : 3.3.0新增功能: 按会话列出服务器上监视器的详细信息。该命令会输出带有相关监视器(路径)的会话(连接)列表。请注意,根据监视器数量的不同,此操作可能会消耗较多资源(即影响服务器性能),请谨慎使用。
-
dirs : 3.5.1版本新增: 以字节为单位显示快照和日志文件的总大小
-
wchp : 新增于3.3.0版本: 按路径列出服务器上监视器的详细信息。该命令会输出包含关联会话的路径(znodes)列表。请注意,根据监视器数量,此操作可能会消耗较多资源(即影响服务器性能),请谨慎使用。
-
mntr : 3.4.0版本新增: 输出可用于监控集群健康状况的变量列表。
$ echo mntr | nc localhost 2185 zk_version 3.4.0 zk_avg_latency 0.7561 - 保留四位小数 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 - 仅在Leader节点暴露 zk_synced_followers 4 - 仅在Leader节点暴露 zk_pending_syncs 0 - 仅在Leader节点暴露 zk_open_file_descriptor_count 23 - 仅Unix平台可用 zk_max_file_descriptor_count 1024 - 仅Unix平台可用
输出内容兼容Java属性格式,且内容可能随时间变化(新增键值)。您的脚本应能适应这些变更。注意:部分键是平台特定的,部分键仅由Leader导出。输出包含多行,格式如下:
key \t value
-
isro : 新增于3.4.0版本: 测试服务器是否运行在只读模式。如果处于只读模式,服务器将响应"ro";如果不是只读模式,则响应"rw"。
-
hash : 新增于3.6.0版本: 返回与zxid关联的树摘要的最新历史记录。
-
gtmk : 以十进制格式获取当前跟踪掩码的64位有符号长整型值。关于可能值的解释,请参见
stmk。 -
stmk : 设置当前跟踪掩码。跟踪掩码为64位,每一位控制服务器上特定类别的跟踪日志记录是否启用。需先在Logback中配置启用
TRACE级别才能查看跟踪日志消息。跟踪掩码的各位对应以下日志记录类别:跟踪掩码位值 0b0000000000 未使用,保留供未来使用 0b0000000010 记录客户端请求(不包括ping请求) 0b0000000100 未使用,保留供未来使用 0b0000001000 记录客户端ping请求 0b0000010000 记录从当前领导者的仲裁节点接收的数据包(不包括ping请求) 0b0000100000 记录客户端会话的添加、删除和验证 0b0001000000 记录监视事件向客户端会话的传递 0b0010000000 记录从当前领导者的仲裁节点接收的ping数据包 0b0100000000 未使用,保留供未来使用 0b1000000000 未使用,保留供未来使用 64位值中所有剩余位均未使用并保留供未来使用。通过计算文档中值的按位OR来指定多个跟踪日志类别。默认跟踪掩码为0b0100110010,因此默认情况下跟踪日志包含客户端请求、从领导者接收的数据包和会话。要设置不同的跟踪掩码,发送包含四字母命令
stmk的请求,后跟表示为64位有符号长整型值的跟踪掩码。此示例使用Perl的pack函数构建启用上述所有跟踪日志类别的掩码,并将其转换为大端字节序的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/[命令名称]"来执行命令,例如http://localhost:8080/commands/stat。命令响应以JSON格式返回。与原始协议不同,命令不再局限于四字母名称,且一个命令可以拥有多个别名;例如,"stmk"也可以被称为"set_trace_mask"。要查看所有可用命令列表,请在浏览器中访问/commands URL(例如http://localhost:8080/commands)。有关如何更改端口和URL的信息,请参阅AdminServer配置选项。
AdminServer默认是启用的,但可以通过以下方式禁用:
- 将zookeeper.admin.enableServer系统属性设置为false。
- 从类路径中移除Jetty。(如果您希望覆盖ZooKeeper的jetty依赖项,此选项很有用。)
请注意,如果AdminServer被禁用,TCP四字母命令接口仍然可用。
为AdminServer配置SSL/TLS
- 生成可在Quorum TLS中找到的keystore.jks和truststore.jks文件。
- 将以下配置设置添加到
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: 历史摘要列表中的交易摘要。每128笔交易记录一次。返回"digests",一个交易摘要对象的列表。
-
dirs : 关于日志文件目录和快照目录大小的信息(以字节为单位)。返回"datadir_size"和"logdir_size"。
-
dump : 会话过期和临时节点的相关信息。注意,根据全局会话和临时节点的数量,此操作可能会很耗时(即影响服务器性能)。返回"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 : 如果集群配置为仲裁模式,则输出该节点的当前领导者状态及领导者位置信息。返回字段包括"is_leader"、"leader_id"和"leader_ip"。
-
monitor/mntr:输出多种有用的监控信息。包括性能统计、内部队列详情以及数据树摘要(还有其他内容)。每个信息项作为单独的字段返回。
-
observer_connection_stat_reset/orst : 重置所有观察者连接统计信息。这是observers命令的配套命令。不会返回新字段。
-
restore/rest : 从当前服务器上的快照输入流恢复数据库。响应负载中返回以下数据:"last_zxid": 字符串 注意:此API设有速率限制(默认每5分钟一次),以防止服务器过载。
-
ruok : 无操作命令,用于检查服务器是否在运行。响应并不一定表示服务器已加入仲裁集群,仅表明管理服务器处于活动状态并绑定到指定端口。不返回新字段。
-
set_trace_mask/stmk : 设置跟踪掩码(需要提供参数)。这是get_trace_mask的写入版本。详情请参阅四字母命令stmk的描述。返回"tracemask"。
-
server_stats/srvr : 服务器信息。返回多个字段,提供服务器状态的简要概览。
-
snapshot/snap : 对当前服务器数据目录进行快照并输出数据流。可选查询参数:"streaming": 布尔值(若未提供该参数则默认为true)通过HTTP头返回以下信息:"last_zxid": 字符串 "snapshot_size": 字符串 注意:此API设有速率限制(默认每5分钟一次)以防止服务器过载。
-
stats/stat : 与 server_stats 相同,但还会返回"connections"字段(详情参见 connections)。注意,根据客户端连接数量的不同,此操作可能会消耗较多资源(即影响服务器性能)。
-
stat_reset/srst : 重置服务器统计信息。这是server_stats和stats返回信息的子集。不会返回新字段。
-
observers/obsr : 关于观察者连接到服务器的信息。在Leader上始终可用,在Follower充当学习主节点时也可用。返回"synced_observers"(整型)和"observers"(每个观察者的属性列表)。
-
system_properties/sysp : 所有已定义的系统属性。每个属性作为独立字段返回。
-
voting_view : 提供集群中当前的投票成员。以映射形式返回"current_config"。
-
watches/wchc : 按会话聚合的监视信息。注意,根据监视数量的不同,此操作可能会很耗资源(即影响服务器性能)。返回"session_id_to_watched_paths"作为映射表。
-
watches_by_path/wchp : 按路径聚合的监视信息。注意,根据监视数量的不同,此操作可能会很耗费资源(即影响服务器性能)。返回"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从配置文件中查找它应该监听的端口。
存储在数据目录中的快照文件属于模糊快照,因为在ZooKeeper服务器拍摄快照期间,数据树仍在持续更新。快照文件名的后缀是zxid(ZooKeeper事务ID),表示快照开始时最后一个已提交事务的ID。因此,快照包含了拍摄过程中对数据树的部分更新。这种快照可能并不对应任何实际存在过的数据树状态,因此我们称之为模糊快照。尽管如此,ZooKeeper仍能利用这种快照进行恢复,因为它利用了更新操作的幂等特性。通过将事务日志重放到模糊快照上,ZooKeeper能获取日志末尾时刻的系统状态。
日志目录
日志目录包含ZooKeeper的事务日志。在执行任何更新之前,ZooKeeper会确保代表该更新的事务被写入非易失性存储。当写入当前日志文件的事务数量达到(可变)阈值时,将创建一个新的日志文件。该阈值使用与影响快照频率相同的参数计算(参见上文的snapCount和snapSizeLimitInKb)。日志文件的后缀是该日志中写入的第一个zxid。
文件管理
快照文件和日志文件的格式在独立ZooKeeper服务器与不同配置的复制ZooKeeper服务器之间保持不变。因此,您可以将这些文件从运行的复制ZooKeeper服务器提取到装有独立ZooKeeper服务器的开发机器上进行故障排查。
使用旧的日志和快照文件,您可以查看ZooKeeper服务器的先前状态,甚至可以恢复该状态。
ZooKeeper服务器会创建快照和日志文件,但从不删除它们。数据和日志文件的保留策略是在ZooKeeper服务器外部实现的。服务器本身只需要最新的完整模糊快照、之后的所有日志文件以及之前的最后一个日志文件。后一个要求是必要的,以包含在此快照启动后发生但当时进入现有日志文件的更新。这是可能的,因为在ZooKeeper中,快照和日志滚动是相对独立进行的。有关设置保留策略和维护ZooKeeper存储的更多详细信息,请参阅本文档中的维护部分。
注意
这些文件中存储的数据未经加密。如果在ZooKeeper中存储敏感数据,需要采取必要措施防止未经授权的访问。此类措施在ZooKeeper外部实现(例如控制对文件的访问权限),具体取决于部署时的个性化配置。
恢复 - 事务日志工具包
更多详情请参阅this
需避免的事项
通过正确配置ZooKeeper,您可以避免以下常见问题:
-
服务器列表不一致:客户端使用的ZooKeeper服务器列表必须与每个ZooKeeper服务器自身维护的列表相匹配。如果客户端列表是实际列表的子集,系统尚能正常工作;但如果客户端持有的服务器列表来自不同的ZooKeeper集群,则会出现严重异常。此外,每个Zookeeper服务器配置文件中的服务器列表也应保持一致。
-
事务日志位置不当:ZooKeeper性能最关键的部分是事务日志。ZooKeeper在返回响应前会将事务同步到存储介质。专用的事务日志设备是保持稳定高性能的关键。将日志放在繁忙的设备上会严重影响性能。如果只有一个存储设备,可以增加snapCount参数值以减少快照文件的生成频率;这虽然不能彻底解决问题,但能为事务日志释放更多资源。
-
Java堆大小设置错误:您需要特别注意正确设置Java最大堆大小。尤其要避免出现ZooKeeper使用磁盘交换的情况。磁盘交换对ZooKeeper来说是致命的。由于所有操作都是有序的,如果一个请求触发了磁盘交换,那么其他排队中的请求很可能也会如此。切记:不要发生交换。在估算时要保守:如果您的机器有4G内存,不要将Java最大堆大小设为6G甚至4G。举例来说,在4G内存的机器上更可能使用3G的堆空间,因为操作系统和缓存也需要占用内存。评估系统所需堆大小的最佳且唯一推荐做法是进行负载测试,确保使用量远低于会导致系统发生交换的临界值。
-
公开可访问的部署:ZooKeeper集群预期在可信计算环境中运行。因此建议将ZooKeeper部署在防火墙后方。
最佳实践
为了获得最佳效果,请注意以下Zookeeper的良好实践列表:
对于多租户安装,请参阅详细介绍ZooKeeper "chroot"支持的章节,这在部署多个应用程序/服务连接到单个ZooKeeper集群时非常有用。
