Zookeeper 管理文档
一、部署
1.1 系统要求
1.1.1 支持系统平台
ZooKeeper由多个组件组成。
一些组件得到了广泛的支持,而其他组件仅在一组较小的平台上得到支持。
Client是Java客户机库,应用程序使用它连接到ZooKeeper集群。
Server是在ZooKeeper集群节点上运行的Java服务器。
Native Client是用C实现的客户机,类似于Java客户机,由应用程序用来连接到ZooKeeper集群。
Contrib指的是多个可选的附加组件。
1.1.2 支持情况
表格中没有提及的系统,可能支持也可能不支持。对于在没有支持的系统中出现的明显报错,社区会去修复,但没有完全支持。
系统/组件 | Client | Server | Native Client | ontrib |
---|---|---|---|---|
GNU/Linux | 开发和生产 | 开发和生产 | 开发和生产 | 开发和生产 |
Solaris | 开发和生产 | 开发和生产 | 不支持 | 不支持 |
FreeBSD | 开发和生产 | 开发和生产 | 不支持 | 不支持 |
Windows | 开发和生产 | 开发和生产 | 不支持 | 不支持 |
Mac OS X | 仅开发 | 仅开发 | 不支持 | 不支持 |
1.1.3 所需软件
ZooKeeper运行在Java 1.8或以上的版本中(不支持JDK 8 LTS, JDK 11 LTS, JDK 12 - Java 9和10),建议一个集群的最小机器数是3个。
在雅虎的应用案例中,ZooKeeper通常运行在RHEL虚拟机中,拥有2核处理器,2G内存和80G IDE硬盘。
1.2 集群(多服务器)部署
ZooKeeper集群需要多数节点正常才能运转,因此最好是2X+1奇数个节点组成,其中X表示允许的最大宕机数。
通常一个集群3台就够了,但是考虑到升级维护时候的可靠性,可以由为5台或以上奇数节点组成。
可靠性还应该考虑其他方面的问题,如所有集群机器都在一台交换机上,那么如果交换机出问题,集群也无法正常运转。
1.2.1 集群设置步骤(每台机器都需要执行)
-
安装
Java JDK
,http://java.sun.com/javase/downloads/index.jsp -
设置
Java
堆大小,需要正确配置以避免ZooKeeper
使用交换内存,如一台4G内存的机器,最大使用3GJava
堆大小。 -
下载
ZooKeeper
安装包,http://zookeeper.apache.org/releases.html。 -
创建任意文件名的配置文件,一般为
zoo.cfg
,并添加以下基础内容:# 配置字段的详情参见下方配置参数说明 tickTime=2000 dataDir=/var/lib/zookeeper/ clientPort=2181 initLimit=5 synclimit=2 # server.x=hostname:仲裁端口:选举端口,3.6.0版本后可以配置多地址,以增强可靠性。 # 可以在dataDir指定的目录中生成一个myid文件来将服务器id指定给每个服务机器。 server.1=zoo1:2888:3888 server.2=zoo2:2888:3888 server.3=zoo3:2888:3888
-
myid
文件内容只能是服务器id
,如server.1
的myid
的内容为1
,该id
必须是唯一的且值介于1-255
直接。如果启用如TTL
节点等扩展功能,由于内部限制,id
必须介于1-254
之间。 -
在与
myid
文件相同的目录下创建initialize
文件,表示预期的数据目录为空。如果存在,则创建空数据库并删除标记文件。如果不存在且数据目录为空,则表示该服务在集群中没有投票权直到数据同步到与leader
保持一致,在与leader
通信前不会填充数据目录。仅在创建新集群时才创建该文件。 -
如果配置文件准备完毕,则可以启动服务器:
$ java -cp zookeeper.jar:lib/*:conf org.apache.zookeeper.server.quorum.QuorumPeerMain zoo.conf # QuorumPeerMain启动ZooKeeper服务,并注册'JMX management beans'允许通过JMX管理控制台来管理。 # ZooKeeper JMX文档,https://zookeeper.apache.org/doc/current/zookeeperJMX.html,给出了详细介绍。 # 可以查看发行版中的bin/zkServer.sh脚本来获取启动示例。
- 通过连接到主机来测试部署的正确性,
Java
环境可以通过如下命令来执行简单操作:
$ bin/zkCli.sh -server 127.0.0.1:2181
- 通过连接到主机来测试部署的正确性,
1.3 单服务和开发环境部署
1.3.1 配置zoo.cfg
tickTime=2000
dataDir=/var/lib/zookeeper
clientPort=2181
13.2 启动实例
bin/zkServer.sh start
二、管理
2.1 ZooKeeper部署方案
ZooKeeper集群稳定性基于两个假设:
1. 集群中仅有少部分机器会发生故障,发生故障可能是机器崩溃或者是网络原因导致与集群的其他机器不能通信。
2. 部署的机器正常的运转,正确运转意味着正确地执行代码,时钟正常工作,并使存储器和网络组件始终如一的运转。
以下各节包含ZooKeeper管理员的注意事项,以最大限度地提高这些假设成立的可能性。其中一些是跨机器的考虑因素,而另一些是部署中每台机器都应该考虑的因素。
2.1.1 跨机器要求
1. 需要2F+1台可以相互通信的机器;
2. 机器间需要保持故障独立,即独立的交换机、电源电路、冷却系统等。
2.1.2 单机要求
如果ZooKeeper服务必须与其他程序共享存储媒介、cpu、内存或网络等资源,这将会显著影响ZooKeeper的性能。
ZooKeeper依靠使用存储媒介记录更改来保持很强的持久性,因此必须保障存储媒介不会阻碍ZooKeeper的操作。
可以做以下操作来尽量避免这种阻塞:
1.事务日志文件必须位于专用的设备上(单独的分区时不够的),因为ZooKeeper是顺序写入日志,而不寻求与其他进程共享日志设备,这会导致寻址和争用,从而导致多秒延迟。
2.确保ZooKeeper不会用到交换内存,因此确保ZooKeeper的最大Java堆内存不大于可使用的实际内存值,详见注意避免事项。
2.2 资源调配
需要考量ZooKeeper的优势和局限。
2.3 维护
ZooKeeper群集几乎不需要长期维护,但是您必须注意以下几点:
2.3.1 持续进行数据目录清理
ZooKeeper数据目录包含的文件是由特定服务集合存储的znode的持久副本,是快照和事务日志文件。
当在znode上发生更改时,这些更改会附加到事务日志文件中。
当事务日志增长到一定程度,将会生成znode当前状态的快照,同时创建新的事务日志文件来存储新的事务。
由于快照生成与事务日志记录是并发执行,这会导致在快照生成期间产生的事务仍然被记录在旧的事务日志文件中,从而导致快照生成前的最后一个事务日志中可能存在比快照中更新的事务。
ZooKeeper默认情况下不会删除旧的快照和事务日志文件,需要用户自己操作。
另外每个服务器环境可能不同,因此管理这些文件的要求可能因安装方式而异。
`PurgeTxnLog`实用工具实现了管理员可以使用的简单保留策略,api文档包含了详细的调用方法,https://zookeeper.apache.org/doc/current/index.html。
下面的示例中,将保留最后一个计数快照及其相应的日志,并删除其他快照。
可以作为计划任务允许,`count`值通常大于3。
$ java -cp zookeeper.jar:lib/slf4j-api-1.7.5.jar:lib/slf4j-log4j12-1.7.5.jar:lib/log4j-1.2.17.jar:conf org.apache.zookeeper.server.PurgeTxnLog <dataDir> <snapDir> -n <count>
`3.4.0`版本开始引入了快照及其相应事务日志的自动清除策略,可以通过`autopurge.snapRetainCount`和`autopurge.purgeInterval`进行配置,详情参见下方配置参数中高级选项说明。
2.3.2 Debug
日志清理
查看2.6章节关于日志的介绍。
使用内置的log4j特性创建一个滚动文件添加器,conf/log4j.properties提供了一个简单的配置示例。
2.4 监管进程
您可能想要一个管理ZooKeeper服务进程(JVM)的监控进程。
ZK服务设计思想是'fail fast',意味着只要发生无法恢复的错误,它就会退出进程。
ZK高可用集群保障在少部分节点故障的情况下,集群整体仍然可以提供服务,且故障节点重启后加重新加入集群。
诸如daemontools(http://cr.yp.to/daemontools.html)或SMF(http://en.wikipedia.org/wiki/Service_Management_Facility)之类的监控进程可以用来管理ZooKeeper服务器,可以确保如果进程异常退出,它会自动重启并重新加入集群,其他的管理进程也可以用,这里只是举例说明。
建议在Windows和Linux上使用以下参数来启动JVM来实现配置ZK服务进程,以便在方式 OutOfMemoryError**错误时终止和转储其堆。
在TzkServer.sh和zkServer.cmd 脚本中分别附带了以下选项:
-XX:+HeapDumpOnOutOfMemoryError -XX:OnOutOfMemoryError='kill -9 %p'
"-XX:+HeapDumpOnOutOfMemoryError" "-XX:OnOutOfMemoryError=cmd /c taskkill /pid %%%%p /t /f"
2.5 监控
ZooKeeper服务可以通过以下三种主要方式之一进行监控:
2.6 日志
ZooKeeper使用SLF4J版本1.7.5作为日志记录基础框架,为了兼容性采用LOG4J,你也可以使用LOGBack或其他的日志框架。
默认配置位于conf/log4j.properties。
log4j要求log4j.properties要么位于工作目录中,要么可以从类目录访问。
2.7 故障排查
-
文件损坏导致的服务无法启动
ZK服务可能会无法读取它的数据库,并且可能因为某些事务日志文件损坏导致无法启动,这在加载ZK数据库时,你可能会看到一些IOException。 这种情况,首先通过‘stat’命令确认集群中其他服务是否正常运行,再确认其他服务节点都正常运行后,可以清理损坏服务器的数据库。 删除'datadir/version-2'和'datalogdir/version-2/'目录下的所有文件。
2.8 、Zookeeper 配置参数
zoo.cfg中可配置参数
2.8.1 基础选项
选项 | 默认值 | 说明 |
---|---|---|
clientPort | - | 监听客户端连接的端口,一般采用2181,无默认值 |
secureClientPort | - | 监听客户端连接的SSL安全端口 ,** clientPort 指定普通纯文本连接,secureClientPort **指定SSL安全连接 ,不配置则表示禁用某种方式,都启用表示混合模式 当用户使用 zookeeper.serverCnxnFactory 和zookeeper.clientCnxnSocket 作为网络插件时,将自动启用 SSL安全连接 |
observerMasterPort | - | 监听的观察者连接端口,用于故障时候的选举投票 |
dataDir | - | 存储内存中的数据库快照的位置,如果没有特殊配置dataLogDir 还会存储数据库更新的事务日志,由于 ZooKeeper 是顺序存取数据到硬盘,配置一个独立的硬盘挂载目录而部署硬盘的某个分区,有利于得到更好的服务性能。 |
tickTime | 2000ms | ZooKeeper 的最小实际单位,用于设置心跳和超时,单位是毫秒 |
2.8.2 高级选项
选项 | 默认值 | 说明 |
---|---|---|
dataLogDir | - | 指定事务日志写入该指定目录而不是dataDir 指定的目录,便于指定专用的事务日志目录,避免与快照文件资源竞争, 建议将 dataLogDir 和dataDir 设置到不同硬盘设备 |
globalOutstandingLimit | 1000 | Java 系统属性:zookeeper.globalOutstandingLimit.,为了防止排队请求耗尽内存,限制系统中未处理的请求数少于 globalOutstandingLimit |
preAllocSize | 64m | Java 系统属性:zookeeper.preAllocSize,为避免 ZooKeeper 以KB 为单位预分配事务日志文件空间,如果频繁创建快照,则应该调小该值,参见snapCount 和snapSizeLimitInKb |
snapCount | 10 0000 | Java 系统属性:zookeeper.snapCount,ZooKeeper 使用快照和事务日志记录其事务,在快照可以获取前,事务日志中记录的事务数由 snapCount 确定,为了避免所有 ZooKeeper 同时创建快照,各个 ZooKeeper 服务中当事务日志中事务数达到[snapCount/2+1 , snapCount ]中的某个随机值时,将创建快照 |
commitLogCount | 500 | Java 系统属性:zookeeper.commitLogCount,ZooKeeper 将在内存中维护最后请求的列表,以便于不太落后的followers 能快速同步,当快照大于 100,000 时将显著提高同步性能。 |
snapSizeLimitInKb | 4194304KB (4GB ) | Java 系统属性:zookeeper.snapSizeLimitInKb,ZooKeeper 使用快照和事务日志记录其事务,在可以获取快照(并滚动事务日志)之前, 记录在事务日志中的事务允许的总字节大小由 snapSize 决定,为了避免所有 ZooKeeper 同时创建快照,各个 ZooKeeper 服务中当事务日志的字节大小达到[ snapSize/2+1 ,snapSize ]中的某个随机值时,将创建快照,每个文件系统都有一个最小的标准文件大小,为了有效允许该功能, snapSize 必须大于该值 |
txnLogSizeLimitInKb | - | Java 系统属性:zookeeper.txnLogSizeLimitInKb,ZooKeeper 事务日志可以更直接的用txnLogSizeLimitInKb 控制,因为 leader 必须扫描磁盘上的日志文件才能找到启动同步的事务,在事务完成同步时,越大的 txn 日志将导致follower 同步越慢。默认情况下,此功能处于关闭状态, 只有 snapCount 和snapSizeLimitInKb 是限制事务日志大小的值。如果启用,则事务日志达到限制时将滚动日志,该值如果设置的小于或等于 preAllocSize ,可能会导致每个事务都会滚动日志,从而引发性能问题。 为了避免这种情况,建议设置为 N * preAllocSize ,且N >= 2 |
maxCnxns | 0 | Java 系统属性:zookeeper.maxCnxns,限制每个 ZooKeeper 服务的每个客户端端口可建立的并发连接总数,可以用于抵御某些 DOS 攻击,默认为0,表示没有限制注意: serverCnxnFactory 和 secureServerCnxnFactory 是分开计数的,因此如果对等连接是适当的类型,最大允许承载 2*maxCnxns 个连接数 |
maxClientCnxns | 60 | 限制由IP 标识的每个客户端可以对集群中ZooKeeper 服务进行的socket 并发连接数,用于防御包括文件描述符耗尽在内的某些 DOS 攻击,设置为0 表示没有限制,默认60 |
clientPortAddress | - | 3.3.0 版本新增属性,侦听客户端连接的地址(IPV4,IPV6、hostname),也就是客户端尝试连接的地址,该选项可选,默认情况下,任何( address/interface/nic )连接到clientPort 都将被侦听到 |
minSessionTimeout | 2*tickTime | 3.3.0 版本新增属性,服务器允许客户端通过的最小会话超时实际 |
maxSessionTimeout | 20*tickTime | 3.3.0 版本新增属性,服务器允许客户端通过的最大会话超时实际 |
fsync.warningthresholdms | 1000ms | Java 系统属性:zookeeper.fsync.warningthresholdms,3.3.4 版本新增属性,当事务日志 fsync 时间超过该值时,就会在log 文件中记录一条告警消息。只能设置为系统属性,默认 1000ms ,fsync扩展 |
maxresponsecacheSize | 400 | Java 系统属性:zookeeper.maxresponsecacheSize,设置为正数,用于确认最近记录的序列化形式缓存的大小, 有助于节省普通 Znode 的序列化成本。指标response_packet_cache_hits 和response_packet_cache_misses 有助于将该值调整为给定的工作负载,设置为 0 将禁用该功能,默认启用,值为400 |
maxGetChildrenresponsecacheSize | 400 | Java 系统属性:zookeeper.maxGetChildrenresponsecacheSize,3.6.0 版本新增属性,与 maxresponsecacheSize 类似,但适用于获取子请求,指标 response_packet_get_children_cache_hits 和response_packet_get_children_cache_misses 有助于将该值调整为给定的工作负载,设置为 0 将禁用该功能,默认启用,值为400 |
autopurge.snapRetainCount | 3 | 3.4.0 版本新增属性,启用后, ZooKeeper 将自动保留dataDir 和 dataLogDir 中与autopurge.snapRetainCount 相同数量的最新的快照和事务日志,并删除其他的快照和事务日志。最小值 3 ,默认3 |
autopurge.purgeInterval | 0 | 3.4.0 版本新增属性,自动清除任务触发的时间间隔(单位:小时),设置为 1 及以上自动触发,默认0 |
syncEnabled | true | Java 系统属性:zookeeper.observer.syncEnabled,3.4.6,3.4.5 版本新增属性,观察者像参与者一样将记录事务并将快照写入磁盘, 这样可以减少观察者重启时的恢复时间, false 禁用,默认true |
fastleader.minNotificationInterval | - | Java 系统属性:zookeeper.fastleader.minNotificationInterval,leader 选举,连续两次通知检查间的时间长度下限,这个时间间隔将影响选举的解决速度, 为了长时间的选举, 策略遵循最小和最大( fastleader.maxNotificationInterval )时间间隔配置 |
fastleader.maxNotificationInterval | - | Java 系统属性:zookeeper.fastleader.maxNotificationInterval,leader 选举,连续两次通知检查间的时间长度上限 |
connectionMaxTokens | 0 | Java 系统属性:zookeeper.connection_throttle_tokens,3.6.0 版本新增属性,这是调整服务器端连接节流器的参数之一,它是一种基于令牌的速率限制机制,具有可选的概率丢弃。 此参数定义令牌桶中的最大令牌数。设置为 0 时,将禁用限制。默认值为0 。 |
connectionTokenFillTime | 1 | Java 系统属性:zookeeper.connection_throttle_fill_time,3.6.0 版本新增属性,这是优化服务器端连接节流器的参数之一,它是一种基于令牌的速率限制机制,具有可选的概率丢弃。 此参数定义用 connectionTokenFillCount 令牌重新填充令牌桶的时间间隔(以毫秒为单位)。默认值为1 。 |
connectionTokenFillCount | 1 | Java 系统属性:zookeeper.connection_throttle_fill_count,3.6.0 版本新增属性,这是优化服务器端连接节流器的参数之一,它是一种基于令牌的速率限制机制,具有可选的概率丢弃。 此参数定义每隔 connectionTokenFillTime 时间添加到令牌桶的令牌数,默认1 |
connectionFreezeTime | -1 | Java 系统属性:zookeeper.connection_throttle_freeze_time,3.6.0 版本新增属性,这是调整服务器端连接节流器的参数之一,它是一种基于令牌的速率限制机制,具有可选的概率丢弃。 此参数定义调整丢弃概率时的间隔(毫秒)。 设置为 -1 时,禁用概率丢弃。默认值为-1 。 |
connectionDropIncrease | 0.02 | Java 系统属性:zookeeper.connection_throttle_drop_increase,3.6.0 版本新增属性,这是调整服务器端连接节流器的参数之一,它是一种基于令牌的速率限制机制,具有可选的概率丢弃。 此参数定义每次要增加的丢弃概率, 节流器每隔 connectionFreezeTime 检查一次,如果令牌桶为空,则丢弃概率增加 connectionDropIncrease 。 |
connectionDropDecrease | 0.002 | Java 系统属性:zookeeper.connection_throttle_drop_decrease,3.6.0 版本新增属性,这是调整服务器端连接节流器的参数之一,它是一种基于令牌的速率限制机制,具有可选的概率丢弃。 此参数定义每次要降低的丢弃概率, 节流器每隔 connectionFreezeTime 检查一次,如果令牌桶超过阈值,则丢弃概率降低 connectionDropDecrease ,阈值= connectionMaxTokens * connectionDecreaseRatio |
connectionDecreaseRatio | Java 系统属性:zookeeper.connection_throttle_decrease_ratio,3.6.0 版本新增属性,这是调整服务器端连接节流器的参数之一,它是一种基于令牌的速率限制机制,具有可选的概率丢弃。 此参数定义了降低丢弃概率的阈值。默认值为0。 | |
zookeeper.connection_throttle_weight_enabled | false | 只有Java 系统属性,3.6.0 版本新增属性,节流时是否考虑连接权重。仅当启用连接限制时有用,也就是 connectionMaxTokens 大于0 ,默认false |
zookeeper.connection_throttle_global_session_weight | 3 | 只有Java 系统属性,3.6.0 版本新增属性,全局会话的权重,它是全局会话请求通过连接节流器所需的令牌数。它必须是不小于本地会话权重的正整数。默认值为 3 。 |
zookeeper.connection_throttle_local_session_weight | 1 | 只有Java 系统属性,3.6.0 版本新增属性,它是本地会话请求通过连接节流器所需的令牌数。它必须是不大于全局会话或续订会话的权重的正整数。默认值为 1 。 |
zookeeper.connection_throttle_renew_session_weight | 2 | 只有Java 系统属性,3.6.0 版本新增属性,重新开始一个会话的权重。它也是重新连接请求通过节流器所需的令牌数。它必须是不小于本地会话权重的正整数。默认值为2。 |
clientPortListenBacklog | 50 | 3.4.14, 3.5.5, 3.6.0 版本新增属性,ZooKeeper 服务socket 连接的套接字积压长度,这控制将在服务器端排队等待ZooKeeper 服务处理的请求数。超过该长度将会收到 30s 网络超时,可能会导致会话过期,默认-1 表示禁用,linux 默认50 个积压。 |
serverCnxnFactory | NIOServerCnxnFactory | Java 系统属性:zookeeper.serverCnxnFactory,指定 serverCnxnFactory 方式,设置为 NettyServerCnxnFactory 以便使用基于TLS 的通信服务,默认NIOServerCnxnFactory |
flushDelay | 0 | Java 系统属性:zookeeper.flushDelay,延迟刷新日志的时间(单位:毫秒), 不影响 maxBatchSize 定义的限制,默认 0 表示禁用,具有高写入速率的集群设置为10-20ms |
maxWriteQueuePollTime | flushDelay/3 | Java 系统属性:zookeeper.maxWriteQueuePollTime,如何 flushDelay 启用,则表示如果没有新的请求,在刷新日志前等待时间,默认 flushDelay/3 |
maxBatchSize | 1000 | Java 系统属性:zookeeper.maxBatchSize,触发刷新日志前服务中允许的事务数量,不影响 flushDelay 定义的限制,默认1000 |
requestThrottleLimit | 0 | Java 系统属性:zookeeper.request_throttle_max_requests, 3.6.0 版本新增属性,RequestThrottler 着手暂停前允许的最大重要请求数,0 表示没有限制。 |
requestThrottleStallTime | 100 | Java 系统属性:zookeeper.request_throttle_stall_time,3.6.0 版本新增属性,最大线程等待时间(单位:毫秒) |
requestThrottleDropStale | true | Java 系统属性:request_throttle_drop_stale,3.6.0 版本新增属性,如果启用,节流器将丢弃过时请求,而不是将他们发送到请求管道。过时请求可能是现在已关闭的连接发送的请求或超过 sessionTimeout 的请求。 |
requestStaleLatencyCheck | false | Java 系统属性:zookeeper.request_stale_latency_check,3.6.0 版本新增属性,启用时如果请求延迟比关联会话超时时间高则任务请求过时,默认禁用 |
requestStaleConnectionCheck | true | Java 系统属性:zookeeper.request_stale_connection_check, 3.6.0 版本新增属性,启用时如果请求连接已经关闭则任务请求过时,默认启用 |
zookeeper.request_throttler.shutdownTimeout | 10000 | 只有Java 系统属性,3.6.0 版本新增属性,RequestThrottler 在请求队列强制关闭之前等待请求队列在关闭期间耗尽的时间(单位:毫秒),默认值为10000 。 |
advancedFlowControlEnabled | - | Java 系统属性:zookeeper.netty.advancedFlowControl.enabled,根据 ZooKeeper 管道的状况,在网络中采用精确的流量控制,避免直接缓冲。它将在Netty 中禁用AUTO_READ 。 |
enableEagerACLCheck | false | Java 系统属性:zookeeper.enableEagerACLCheck,如果设置为true ,在将请求发送给仲裁之前,将会为每个本地服务的写请求启用ACL 检查,默认false |
maxConcurrentSnapSyncs | 10 | Java 系统属性:zookeeper.leader.maxConcurrentSnapSyncs, 单个 leader 或follower 可以同时服务的最大快照同步数,默认10 |
maxConcurrentDiffSyncs | 100 | Java 系统属性:zookeeper.leader.maxConcurrentDiffSyncs,单个 leader 或follower 可以同时服务的最大差异同步数,默认100 |
digest.enabled | false | Java 系统属性:zookeeper.digest.enabled,3.6.0 版本新增属性,在从磁盘加载数据库、追赶和跟踪 leader 时,添加摘要功能以检测ZooKeeper 内部的数据不一致性,它根据报告中提到的 adHash 对DataTree 进行增量哈希检查。其思想很简单, DataTree 的哈希值将根据数据集的变化进行增量更新。leader 在准备txn 时,会根据公式发生的变化预先计算树的哈希值:current_hash = current_hash + hash(new node data) - hash(old node data) ,如果是创建新节点,旧节点数据的哈希值将为0, 如果是删除节点操作,新节点数据的哈希值将为0。 此哈希值将与每个 txn 关联,以表示将txn 应用到数据树后的预期哈希值,它将被发送给具有原始建议的follower 。leader 将在将 txn 应用到数据树后将实际哈希值与 txn 中的哈希值进行比较,如果不相同,则报告不匹配值。这些摘要值还将与磁盘上的每个 txn 和快照保持一致,因此当服务器重新启动并从磁盘加载数据时,它将比较并查看是否存在哈希不匹配,这将有助于检测磁盘上的数据丢失问题。对于实际的 hash 函数,我们在内部使用CRC ,它不是无碰撞的hash 函数,但是它比无碰撞的hash函数更有效,而且碰撞的可能性非常少,已经可以满足我们这里的需要了。此功能向后和向前兼容,因此它可以安全地滚动升级、降级、启用和稍后禁用,而不存在任何兼容问题。以下是已涵盖和测试的场景: 1. 当 leader 使用新代码运行,而follower 使用旧代码运行时,摘要将附加到每个 txn 的末尾,follower 将仅读取标题和txn 数据,txn 中的消化值将被忽略。它不会影响follower 阅读和处理下一个txn 。2. 当 leader 使用旧代码运行而follower 使用新代码运行时,摘要将不会与txn 一起发送,当follower 尝试读取摘要时,它将抛出捕获的EOF ,并使用设置为null 的摘要值进行优雅的处理。3. 当加载带有新代码的旧快照时,它在尝试读取不存在的摘要值时将抛出 IOException ,并且将捕获异常并将摘要设置为null ,这意味着我们在加载此快照时不会比较摘要,这在滚动升级期间会发生。4. 用旧代码加载新快照时,反序列化数据树后将成功完成,快照文件末尾的摘要值将被忽略。 5.带标志更改的滚动重启场景与上面讨论的第 1 和第2 个场景类似,如果leader 启用而follower 未启用,则digest 值将被忽略,follower 在运行时不会比较digest ;如果禁用了 leader ,但启用了follower ,follower 将获得EOF 异常,该异常将被优雅地处理。注意:当前摘要计算排除了 /zookeeper 下的节点,因为/zookeeper/quota 节点中存在潜在的不一致性,我们可以在修复该问题之后包含该节点。默认情况下,此功能已禁用,请设置 true 以启用它。 |
snapshot.trust.empty | false | 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 | false | Java 系统属性:zookeeper.audit.enable,3.6.0 版本新增属性,默认情况下,将禁用审计日志。设置为true 以启用它。默认值为false 。有关详细信息,请参阅ZooKeeper 审计日志。 |
audit.impl.class | Java 系统属性:zookeeper.audit.impl.class,3.6.0 版本新增属性,审计记录器的实现类,默认情况下log4j 继承自org.apache.zookeeper.audit .Log4jAuditLogger 审计记录器。有关详细信息,请参阅ZooKeeper 审计日志。 | |
largeRequestMaxBytes | 1024*1024*1024 | Java 系统属性:zookeeper.largeRequestMaxBytes,3.6.0 版本新增属性,即将达到的请求的最大字节数,如果超过限制将被关闭,默认 1024*1024*1024 |
largeRequestThreshold* | -1 | Java 系统属性:zookeeper.largeRequestThreshold,3.6.0 版本新增属性,将请求视为大请求的阈值, -1 表示将所有请求都视为小请求。 |
outstandingHandshake.limit | - | 只有Java 系统属性:zookeeper.netty.server.outstandingHandshake.limit, 在请求途中的最大 TLS 连接数,超过限制将在握手前被拒绝。该属性不会限制最大 TLS 并发数,但有助于避免请求途中的TLS 握手过多时由于TLS 握手超时导致的羊群效应,设置为250 可以有效避免羊群效应。 |
2.8.3 集群选项
选项 | 默认值 | 说明 |
---|---|---|
electionAlg | 3 | 1 :基于UDP 的非身份验证版本的快速leader 选举;2 :基于UDP 的身份验证版本的快速leader 选举;3 :基于TCP 版本的快速leader 选举。3.2.0 版本默认用的3 ,之前也用的1 和2 ,3.4.0 版本中1 和2 被启用,3.6.0 版本后由于只提供FastleaderElection ,因此升级时必须关闭所有服务,并设置electionAlg=3 ,或删除改行设置。 |
initLimit | - | 允许follower 连接并同步leader 的时间量,单位为tickTime ;如果 ZooKeeper 管理数量很大,则需要适当增加该值。 |
connectToLearnerMasterLimit | Java 系统属性:zookeeper.connectToLearnerMasterLimit,leader 选举后follower 连接到leader 的时间,默认为initLimit 的值,当initLimit 很高时使用,这样连接到leader 不会导致更高的超时。 | |
leaderServes | yes | Java 系统属性:zookeeper.leaderServes,leader 机器允许客户端连接,默认yes ;leader 机器协调更新,为了获取更高的更新吞吐量可以设置不接受客户机连接稍微牺牲读取吞吐量,以将重点放在协调上。当前集群中由三个以上服务端时候,建议启用。 |
server.x=[hostname]:nnnnn[:nnnnn] etc | - | 组成ZooKeeper 集群的服务器。当服务启动后,将会通过查看数据目录下的 myid 文件确认是集群中的哪个服务,文件中包含了与server.x 中x 对应的服务器的ASCII 编码。ZooKeeper 集群中每个服务器配置中的服务器列表必须有对应开启的ZooKeeper 服务。两个 nnnnn 代表端口号,第一个用于连接leader ,第二个用于leader 选举,如果是一台服务器上模拟集群,可以通过不同端口来区分。ZooKeeper 3.6.0 版本后可以为每个ZooKeeper 服务器指定多个地址,详见ZOOKEEPER-3188,如果要开启该功能,需要设置multiAddress.enabled 为true ,多地址有助于增强可用性和网络恢复能力。当服务器使用多个物理网络接口时,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 ,启用此功能将会更改服务期间仲裁协议,旧版本如果不支持多地址功能,则无法在滚动升级时开启该功能。如果仍然需要该功能,则需要先不开启该功能进行滚动升级,然后利用新配置开启该功能。 |
synclimit | - | 允许follower 与leader 同步应答的tick 数(tickTime 的倍数),如果follower 远远落后于leader 则将被丢弃 |
group.x=nnnnn[:nnnnn] | 启用分级仲裁结构,x 表示组标识符,= 号后边的数字nnnnn 代表服务器标识符,服务器标识符间用冒号: 分隔;组与组之间必须没有交集,并且所有组的并集为一个ZooKeeper 集群。 | |
weight.x=nnnnn | 1 | 与group 一起使用,在仲裁时分配权重,x 为组标识符。ZooKeeper 有几个部分需要投票,比如领导人选举和原子广播协议。默认情况下所有服务器的权重都是 1 ,如果配置只定义了组但没有分配权重,则所有服务器的权重都是1 。你可以从这里查看例子。 |
cnxTimeout | 5s | Java 系统属性:zookeeper.cnxTimeout,设置 leader 选举时,打开连接的超时时间,仅适用于electionAlg=3 的情况,默认5s |
quorumCnxnTimeoutMs | -1 | Java 系统属性:zookeeper.quorumCnxnTimeoutMs,设置leader 选举时,从连接读取的超时时间,仅适用于electionAlg=3 的情况,默认是-1 ,表示使用synclimit * tickTime 作为超时时间 |
standaloneEnabled | true | 3.5.0 版本新增属性,当设置为false 时,单节点可以以replicated 复制模式允许,单个参与者可以与观察者一起运行,集群可以向下配置到一个新节点,并从一个节点向上配置。为了向后兼容,默认为 true 。可以使用 QuorumPeerConfig 的setStandaloneEnabled 方法或在服务配置中指定standaloneEnabled=false|true 来设置它。 |
reconfigEnabled | false | 3.5.3 版本新增属性,控制动态配置功能的开启或禁用。如果启用,有权限的用户可以通过客户端或 API 进行动态修改配置。如果禁用,包括超级用户在内的所有用户都无权进行动态修改配置,如果操作就会报错。 可以使用 QuorumPeerConfig 的setReconfigEnabled 方法或在服务配置中指定reconfigEnabled=false|true 来设置它,默认false 。集群中所有服务器的该值应该保持一致,如果不同会导致服务器间出现不一致情况。 如果 leader 设置为true 则集群将启用该功能,反之禁用,如果发生了重新选举,则可能导致出现结果与预期不符。 |
4lw.commands.whitelist | srvr | Java 系统属性:zookeeper.4lw.commands.whitelist,3.5.3 版本新增属性,逗号分隔的ZooKeeper 四字命令白名单,名单类的命令用户才可以使用。默认情况下白名单只包括 srvr 命令共zkServer.sh 使用,配置示例如下:4lw.commands.whitelist=stat, ruok, conf, isro ;如果想要启用所有四字命令,可以用 * 星号指代所有:4lw.commands.whitelist=* |
tcpKeepAlive | false | Java 系统属性:zookeeper.tcpKeepAlive,3.5.4 版本新增属性,设置为true 表示在集群成员间选举的socket 套接字上加上TCP KeepAlive 标志,使成员间可以保持长连接。长时间的空闲连接,可能会导致某些 NAT 或防火墙终止或失去状态。该设置依赖于操作系统的 KeepAlive 设置,默认false |
electionPortBindRetry | 3 | Java 系统属性:zookeeper.electionPortBindRetry,ZooKeeper 服务连接leader 选举端口失败的重连次数。默认是3 ,如果是容器特别是K8S 环境中,则应该设置为0 ,表示尝试无限次或增加尝试次数,以克服DNS 解析方面的问题。 |
observer.reconnectDelayMs | 0ms | Java 系统属性:zookeeper.observer.reconnectDelayMs,尝试重连的间隔时间,默认0ms |
observer.election.DelayMs | 200ms | Java 系统属性:zookeeper.observer.election.DelayMs,在断开连接后延迟观察员参加leader 选举,以防止投票同行在这个过程中意外增加负担。默认200ms |
localSessionsEnabled 和 localSessionsUpgradingEnabled | false | 3.5.0 版本新增属性,可选值trUe 或false ,默认都是false ;localSessionsEnabled=true 开启本地会话,localSessionsUpgradingEnabled=true 按需将本地会话升级为全局会话,需要同时开启 localSessionsEnabled 。 |
2.8.4 加密、身份验证和授权选项
选项 | 默认值 | 说明 |
---|---|---|
DigestAuthenticationProvider.superDigest | false | Java 系统属性:zookeeper.DigestAuthenticationProvider.superDigest,3.2.0 版本新增属性,默认禁用。允许 ZooKeeper 集群管理员以超级用户身份访问znode 层次结构,被认证为超级用户的用户不会进行ACL 检查。org.apache.zookeeper.server.auth.DigestAuthenticationProvider 可以用参数super: 调用生成superDigest 。在启动每个服务时提供super: 作为系统属性值。在客户端向服务端获取身份验证时,传递 Digest 方案和super: 的身份验证数据。注意身份验证数据是以明文方式传递,因此最好在内网或加密连接中使用此方法。 |
X509AuthenticationProvider.superUser | - | Java 系统属性:zookeeper.X509AuthenticationProvider.superUser,使用SSL 方式允许ZooKeeper 集群管理员以超级用户身份访问znode 层次结构,被认证为超级用户的用户不会进行ACL 检查。当此参数设置为X500 主体名称时,只有具有该主体的经过身份验证的客户端才能绕过ACL 检查,并对所有Znode 具有完全权限。 |
zookeeper.superUser | - | Java 系统属性:zookeeper.superUser,与zookeeper.X509AuthenticationProvider.superUser, 但是对基于 SASL 的登录是通用的,它存储可以作为 super 用户访问znode 层次结构的用户的名称。 |
ssl.authProvider | - | Java 系统属性:zookeeper.ssl.authProvider,用于安全客户端验证的zookeeper.X509AuthenticationProvider的指定子类,对于不使用JKS 的证书密钥基础结构中很有用。扩展javax.net.ssl.X509KeyManager 和javax.net.ssl.x509trustmanager以从SSL 堆栈中获取所期性能是必要的。要使用自定义的身份验证程序,请为自定义程序选定scheme 方案名,并设置zookeeper.ssl.authProvider=[scheme],这样才能把自定义程序加载到ProviderRegistry 中,并使用它进行身份验证。 |
zookeeper.ensembleAuthName | - | Java 系统属性:zookeeper.ensembleAuthName,3.6.0 版本新增属性,以逗号分隔的集群的有效名称或别名列表。客户端可以提供想要连接的集群名称作为集群方案的凭证。EnsembleAuthenticationProvider 将对照列表验证客户端提供的凭据以接收请求,如果凭据不在列表中,则被拒绝连接,可以防止客户端连接到错误的集群中。 |
zookeeper.sessionRequireClientSASLAuth | false | Java 系统属性:zookeeper.sessionRequireClientSASLAuth,3.6.0 版本新增属性,设置为true ,服务端将只接收通过SASL 了身份验证的客户端的请求和连接。未配置SASL 身份验证或配置SASL 但身份验证失败(即凭据无效)的客户端将无法与服务器建立会话。产生错误代码-124 ,这种情况下Java 和C 客户端将关闭与服务端的会话,并不再尝试重连。默认false 。该属性否定了zookeeper.allowSaslFailedClients 属性,所以即便设置了允许SASL 身份验证失败的客户端登录,客户端也无法与服务端建立会话。 |
sslQuorum | false | Java 系统属性:zookeeper.sslQuorum,3.5.5 版本新增属性,启用加密仲裁通信,默认false |
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 版本新增属性,指定 Java 密钥库的文件路径,包括客户端和仲裁TLS 连接证书和对应用于解锁文件的密码。 |
ssl.keyStore.type 和ssl.quorum.keyStore.type | null | Java 系统属性:zookeeper.ssl.keyStore.type 和zookeeper.ssl.quorum.keyStore.type, 3.5.5 版本新增属性,指定证书和密钥文件格式,可选值有JKS ,PEM , PKCS12 或 null (null 表示根据文件名自行检测) |
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.type 和ssl.quorum.trustStore.type | null | Java系统属性:**zookeeper.ssl.trustStore.type** 和**zookeeper.ssl.quorum.trustStore.type**, 3.5.5版本新增属性,指定客户端和仲裁信任库的文件格式,可选值有 JKS, PEM, PKCS12或 null( null`表示根据文件名自行检测) | |
ssl.protocol 和ssl.quorum.protocol | TLSv1.2 | Java 系统属性:zookeeper.ssl.protocol 和zookeeper.ssl.quorum.protocol,3.5.5 版本新增属性,指定要在客户端和仲裁TLS 协商中使用的协议。 |
ssl.enabledProtocols 和ssl.quorum.enabledProtocols | TLSv1.2 | Java 系统属性:zookeeper.ssl.enabledProtocols 和zookeeper.ssl.quorum.enabledProtocols,3.5.5 版本新增属性,指定客户端和Quorum TLS 协商中启用的协议。默认为protocol 属性的值。 |
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 | null | Java 系统属性:zookeeper.ssl.context.supplier.class 和zookeeper.ssl.quorum.context.supplier.class,3.5.5 版本新增属性,指定用于在客户端和仲裁SSL 通信中创建SSL 上下文的类,这允许您使用自定义SSL 上下文并实现以下场景:1. 使用硬件密钥库,使用 PKCS11 或类似的东西加载。2.您无权访问软件密钥库,但可以从其容器中检索已构建的 SSLContext 。默认值: null |
ssl.hostnameVerification 和ssl.quorum.hostnameVerification | true | Java 系统属性:zookeeper.ssl.hostnameVerification 和zookeeper.ssl.quorum.hostnameVerification,3.5.5 版本新增属性,指定是否在客户端和仲裁TLS 协商过程中启用hostname 验证。禁用它仅建议用于测试目的。默认值:true |
ssl.crl 和ssl.quorum.crl | false | Java 系统属性:zookeeper.ssl.crl和zookeeper.ssl.quorum.crl,3.5.5 版本新增属性,指定是否在客户端和仲裁TLS 协议中启用证书吊销列表。默认值:false |
ssl.ocsp 和ssl.quorum.ocsp | false | Java 系统属性:zookeeper.ssl.ocsp和zookeeper.ssl.quorum.ocsp,3.5.5 版本新增属性,指定客户端和仲裁TLS 协议中是否启用联机证书状态协议。默认值:false |
ssl.clientAuth 和ssl.quorum.clientAuth | need | Java 系统属性:zookeeper.ssl.clientAuth和zookeeper.ssl.quorum.clientAuth,3.5.5 版本新增属性,在3.5.7 版本终止。指定用于验证来自客户端的ssl 连接的选项,有效值如下:none :服务端不请求客户端身份验证,want :服务端将会请求客户端身份验证,need :服务端将要求客户端身份验证。 |
ssl.handshakeDetectionTimeoutMillis 和 ssl.quorum.handshakeDetectionTimeoutMillis | - | Java 系统属性:zookeeper.ssl.handshakeDetectionTimeoutMillis 和 zookeeper.ssl.quorum.handshakeDetectionTimeoutMillis,3.5.5 版本新增属性,待定。 |
client.portUnification | false | Java 系统属性:zookeeper.client.portUnification ,指定客户端端口必须接收SSL 安全连接(与客户端安全连接端口配置相同),默认false |
authProvider | - | Java 系统属性:zookeeper.authProvider),可以指定多个身份验证程序类,通常用于指定多个SASL 身份验证提供程序类,如:authProvider.1=org.apache.zookeeper.server.auth.SASLAuthenticationProvider |
kerberos.removeHostFromPrincipal | false | Java 系统属性:zookeeper.kerberos.removeHostFromPrincipal,你可以指示ZooKeeper 在验证期间从客户机主体中删除主机,如将zk/[email protected] 验证为[email protected] |
kerberos.removeRealmFromPrincipal | Java 系统属性:zookeeper.kerberos.removeRealmFromPrincipal,你可以指示ZooKeeper 在验证期间从客户机主体中删除域,如将zk/[email protected] 验证为zk/hostname | |
multiAddress.enabled | false | Java 系统属性:zookeeper.multiAddress.enabled,3.6.0 版本新增属性,启用该功能可以为 ZooKeeper 服务指定多个地址以提高可用性,如果集群中有3.6.0 以前的旧版本,则不支持升级期间启用该功能,默认false |
multiAddress.reachabilityCheckTimeoutMs | Java 系统属性:zookeeper.multiAddress.reachabilityCheckTimeoutMs,3.6.0 版本新增属性,ZooKeeper 将执行ICMP ECHO 请求或尝试在目标主机的TCP 端口7 上建立连接(Echo ),以便找到可以访问的地址。该属性设置可达性检查的超时时间,多个地址检查是并发执行的,因此该值为最长超时时间。必须启用 multiAddress.enabled 才有效。 |
2.8.5 实验选项/特性
选项 | 默认值 | 说明 |
---|---|---|
Read Only Mode Server | false | Java 系统属性:readonlymode.enabled,3.4.0 版本新增属性,设置为 true ,服务器将启用只读模式(ROM ),默认false 。启用 ROM 将允许客户端连接到支持ROM 服务,即使服务已经从仲裁中分离,这种模式下客户端仍然可以从 ZK 服务中读取值,但不能写入值和看到其他客户端的变化。 |
2.8.6 不安全选项
选项 | 默认值 | 说明 |
---|---|---|
forceSync | - | Java 系统属性:zookeeper.forceSync,3.4.0 版本新增属性,设置为yes ,要求更新完成前将内容同步更新到事务日志媒介,设置为no 则与之相反。 |
jute.maxbuffer | 0xFFFFFF | Java 系统属性:jute.maxbuffer,此选项只能设置为 Java 系统属性,不带zookeeper前缀。指定 znode 中可以存储的最大数据大小,单位字节,默认0xFFFFFF (1048575 )字节,略低于1M 。如果要更改该属性,必须在所有服务端和客户端上设置,否则会出现问题; 如果客户端的该值大于服务端的该值,客户端写入数据时服务端会报错java.io.IOException: Len error; 如果客户端的该值小于服务端的该值,客户端读取该值长度的数据时,客户端将会报错java.io.IOException: Unreasonable length 或 Packet len is out of range!; 生产环境中因为以下原因不建议将该值增加到超过默认值: 1. 大尺寸的 znode 会导致不必要的延迟峰值,降低吞吐量。2. 大尺寸的 znode 会导致leader 与follower 间的同步不可预测且不收敛(有时候会超时),从而导致仲裁不稳定。 |
jute.maxbuffer.extrasize | - | Java 系统属性:zookeeper.jute.maxbuffer.extrasize,3.5.7 版本新增属性,在处理客户端请求时,在事务持久化前,ZooKeeper 会在请求中添加一些附加信息。在此之前,该值固定为1024 字节,对于许多场景,特别是jute.maxbuffer 的值大于1M 且请求类型为multi 时,固定值是不足的;为了应对所有常见,将该值从固定值 1024 增加到jute.maxbuffer 大小,也可以通过jute.maxbuffer.extrasize 直接配置。通常不需要更改,因为默认就是最佳值。 |
skipACL | - | Java 系统属性:zookeeper.skipACL,跳过ACL 检查,这可以调高吞吐量,但是会给予用户对数据数的完整访问权限。 |
quorumListenOnAllIPs | false | 如果设置为true ,ZooKeeper 服务端将会从所有可用的IP 地址侦听其对等方的连接,而不仅仅是配置文件配置的服务器列表中配置的地址。会影响处理ZAB 协议和快速leader 选举协议的连接。 |
multiAddress.reachabilityCheckEnabled | true | Java 系统属性:zookeeper.multiAddress.reachabilityCheckEnabled,3.6.0 版本新增属性,从3.6.0 版本开始,,ZooKeeper 将执行ICMP ECHO 请求或尝试在目标主机的TCP 端口7 上建立连接(Echo ),以便找到可以访问的地址。只有配置了多个地址才会发生,当你尝试在一台机器上启用多个成员的集群(如 11+ ),如果达到了某些ICMP 速率限制,可达性检查可能会失败。设置为 false 可用禁用可达性检查,默认true ,禁用可达性检查会导致集群在出现网络故障时无法正确的调整,因此仅建议在测试期间禁用可达性检查。仅在设置了 multiAddress.enabled=true 时才有效。 |
2.8.7 禁用数据目录自动创建
选项 | 默认值 | 说明 |
---|---|---|
datadir.autocreate | false | 3.5.0 版本新增属性,禁用数据目录自动创建,如果配置文件中指定的数据目录不存在, ZooKeeper 服务默认会自动创建,在某些情况下可能会带来风险。比如:如果修改了正在允许中的 ZooKeeper 服务的dataDir 参数,然后重启服务,依据自动创建原则,这会创建这个新的不存在的目录并使用空的znode 命名空间提供服务,这将会导致数据分裂(即数据存在于新旧两个目录)。因此最好有一个选项来关闭自动创建。 一般来说,对于生产环境,应该这样做,但不幸的是,目前无法更改默认的遗留行为,因此必须根据具体情况进行更改。这个问题遗留给用户和 ZooKeeper 的以后的发行版。使用 zkServer.sh 启动服务时,可用通过设置环境变量**ZOO_DATADIR_autocreate_disABLE=1 来禁用自动创建。如果是直接使用Java 命令指定启动类,可用添加Java 参数zookeeper.datadir.autocreate=false ,即 java -Dzookeeper.datadir.autocreate=false ,禁用自动创建功能后,如果数据目录不存在,则会报错并拒绝启动。 zkServer-initialize.sh脚本被提供来支持该新特性。 如果禁用自动创建功能,用户需要安装 ZooKeeper ,并手动创建数据目录和txnLog (事务日志)目录,才能正确启动服务。运行zkServer-initialize.sh**会创建所需目录,并可选的设置 myid 文件。即使未启用自动创建目录,也可以使用该脚本, 用户也会 因为不清楚如何设置(包括设置 myid 文件)而使用该脚本。该脚本只确保数据目录的生成,而不会生成配置文件,且需要一个配置才能运行。 |
2.8.8 启用数据库存在性验证
选项 | 默认值 | 说明 |
---|---|---|
db.autocreate | - | 3.6.0 版本新增属性,启用数据库存在性验证,当找不到数据数时候,服务器启动的默认行为是将 zxid 设置为0 并作为选举成员加入仲裁。如果某个事件(如流氓操作 rm -rf )在服务关闭时删除了数据目录,可能会因此选举出缺少事务的leader ,这是非常危险的。启用 db 存在性验证将在未找到数据树时更改启动时的行为:服务器作为无投票权参与者加入集群,直到它能够与 leader 同步并获取集群数据的最新版本。要创建预期的空数据树,用户需要将 initialize 文件放置到myid 文件所在目录下,启动时服务器将检查并删除该文件。如果是直接使用 Java 命令指定启动类,可用添加Java 参数zookeeper.db.autocreate=false,即 java -Dzookeeper.db.autocreate=false 。运行zkServer-initialize.sh脚本将会创建所需的初始化文件。 |
2.8.9 性能调试选项
'3.5.0'版本新增属性,为了提高读吞吐量,对几个子系统进行了改造。包括'NIO通信子系统'和'请求处理管道'(Commit Processor)。
'NIO'是默认的客户端和服务器间的通信子系统,它的线程模型包括:1-N个接收器'acceptor'线程,1-N个选择器'selector'线程和1-M个'socket I/O'工作线程。
在'请求处理管道'(Commit Processor)中,可用将系统配置为一次处理多个读请求,同时保持相同的一致性保证(写入后读取相同的会话),
'Commit Processor'的线程模型包括1个主线程和1-N个工作线程。
默认值旨在使专用`ZooKeeper`机器上的读吞吐量最大化。两个子系统都需要足够的线程来实现峰值读取吞吐量。
选项 | 默认值 | 说明 |
---|---|---|
zookeeper.nio.numSelectorThreads | sqrt(sum(cpu)/2) | 只有Java 系统属性:zookeeper.nio.numSelectorThreads,'3.5.0’版本新增属性。NIO 选择器线程的数量,最少1 个,建议多个。默认值是 sqrt(sum(cpu)/2) ,即cpu 个数的一半的平方根。 |
zookeeper.nio.numWorkerThreads | 2*sum(cpu) | 只有Java 系统属性:zookeeper.nio.numWorkerThreads,'3.5.0’版本新增属性。NIO 工作线程的数量,如果设置为0 ,则选择器线程直接执行套接字I/O ,默认是cpu 核心数的两倍。 |
zookeeper.commitProcessor.numWorkerThreads | 1*sum(cpu) | 只有Java 系统属性:zookeeper.commitProcessor.numWorkerThreads,'3.5.0’版本新增属性。 Commit Processor 工作线程的数量,如果设置为0 ,则主线程将直接处理请求,默认值是cpu 的核心数。 |
zookeeper.commitProcessor.maxReadBatchSize | 1*sum(cpu) | 只有Java 系统属性:zookeeper.commitProcessor.maxReadBatchSize, 在切换到处理请求前,从等待处理的请求队列中处理的最大读取数。 如果值小于 0 (默认),则每当有本地写入或等待的提交时都会进行切换。较高的读取批大小,将会延迟提交处理,从而导致提供过时数据。如果已知读取以固定大小批的形式到达,那么将该批大小与该属性的值匹配可以平滑队列性能。 由于读取是并行处理的,建议将值设置为匹配 zookeeper.commitProcessor.numWorkerThread (默认为cpu 核心数)或更低。 |
zookeeper.commitProcessor.maxCommitBatchSize | 1 | 只有Java 系统属性:zookeeper.commitProcessor.maxCommitBatchSize, 处理读请求前处理的最大提交数。我们将会处理尽可能多的远程或本地提交数,直到达到该计数。高 提交批大小 将在处理更多提交时,延迟读取 ,低提交批大小将有利于读取。建议仅在集群提供高提交率的工作负载服务时设置该值。 如果已知写入以一定数量的批到达,则将该批大小与此属性的值匹配可以平滑队列性能。 一般方法是将此值设置为等于集群大小,以便当前服务器在处理每批时能够概率处理与其直连的客户之一相关的写入。 默认 1 ,不支持负值和0 值。 |
znode.container.checkIntervalMs | 60,000 | 只有Java 系统属性,3.6.0 版本新增。候选容器和 TTL 节点每次检查的时间间隔,单位毫秒。 |
znode.container.maxPerMinute | 10000 | 只有Java 系统属性,3.6.0 版本新增。每分钟可删除的最大容器和 ttl 节点数。这样可以防止在删除容器时出现羊群现象。 默认值为 10000 。 |
znode.container.maxNeverUsedIntervalMs | 0 | 只有Java 系统属性,3.6.0 版本新增。从未包含任何子级的容器的保留时间,单位毫秒。 需要设置的足够长,以便客户端创建容器,执行任何需要的工作以及创建子级。 默认 0 ,表示不会删除从未包含任何子级的容器。 |
2.8.10 调试可观察性配置
从'3.6.0'版本开始,为了更易于调试,增加了以下选项。
选项 | 默认值 | 说明 |
---|---|---|
zookeeper.messageTracker.BufferSize | 10 | 只有Java 系统属性,控制存储在MessageTracker 中的最大消息数。值必须是正数,默认是 10 。MessageTracker 是3.6.0 引入的,用于记录服务器(包括follower 和observer )与leader 间断开连接时的最后一组消息。这些消息将被转存到 ZooKeeper 的日志文件中,有助于重建断开连接时服务器的状态,对调试非常有用。 |
zookeeper.messageTracker.Enabled | false | 只有Java 系统属性,设置为true ,将会启用MessageTracker 来跟踪和记录消息。 |
2.8.11 AdminServer`配置
选项 | 默认值 | 说明 |
---|---|---|
admin.portUnification | false | Java 属性:zookeeper.admin.portUnification,3.6.0 版本新增,启用管理端口,接受 HTTP 和HTTPS 通信,默认不启用。 |
admin.enableServer | true | Java 属性:zookeeper.admin.enableServer,3.5.0 版本新增,设置为 false 禁用AdminServer ,默认时启用的 |
admin.serverAddress | 0.0.0.0 | Java 属性:zookeeper.admin.serverAddress,3.5.0 版本新增,嵌入式 Jetty 服务器侦听的地址。默认为0.0.0.0 |
admin.serverPort | 8080 | Java 属性:zookeeper.admin.serverPort,3.5.0 版本新增,嵌入式Jetty 服务器侦听的端口。默认为8080 |
admin.idleTimeout | 30,000 | Java 属性:zookeeper.admin.idleTimeout,3.5.0 版本新增,设置一个连接在接收和发送数据前可用等待的最大空闲时间,单位毫秒 |
admin.commandURL | /commands | Java 属性:zookeeper.admin.commandURL,3.5.0 版本新增,用于列出和发送命令的相对于根URL 的URL 地址,默认/commands |
2.8.12 监控程序
默认情况下,ZooKeeper使用AdminServer和四字命令接口公开有用的指标。
3.6.0版本后你可用使用不同的监控提供者,展示指标到你喜欢的系统中。
3.6.0版本的二进制包捆绑了Prometheus.io。
3.6.0版本开始,以下选项用于配置监控。
选项 | 默认值 | 说明 |
---|---|---|
metricsProvider.className | - | 设置为org.apache.zookeeper.metrics.prometheus.PrometheusMetricsProvider 启用Prometheus.io 方案 |
metricsProvider.httpPort | 7000 | Prometheus.io将会启用一个Jetty 服务并绑定到该端口,默认时7000 。Prometheus.io 的站点是http://hostname:httPort/metrics |
metricsProvider.exportJvmInfo | true | 如果设置为true ,Prometheus.io 将导出关于JVM 的有用指标。 |
三、使用Netty
框架进行通信
NETTY是一个基于NIO的客户端和服务端通信框架,通过使用NIO它简化了Java应用程序网络层级的很多复杂度。
另外NETTY还内置了对加密(SSL)和身份验证(certificates)的支持,这些是可以单独开启和关闭的可选功能。
在3.5+的版本中,
对于ZooKeeper服务器可以通过设置环境变量‘zookeeper.serverCnxnFactory’到‘org.apache.zookeeper.server.NettyServerCnxnFactory’来使用Netty而不是NIO(默认选项);
对于客户端,设置'zookeeper.clientCnxnSocket'到'org.apache.zookeeper.ClientCnxnSocketNetty'。
3.1. 启用Quorum TLS
3.5.5 版本新增属性。
基于Netty框架,ZooKeeper群可以设置为在其通信信道中使用TLS加密。本节介绍如何在Quorum通信上设置加密。
请注意,Quorum TLS封装了保护leader选举和Quorum通信协议的安全。
-
创建
SSL keystore JKS
以存储本地凭据应该为每个ZK实例创建keystore,本例中我们生产自签名的证书并和私钥一起存储在‘keystore.jks’中,这仅用于测试目的,生产环境中你需要一个官方证书。 请注意,别名(-alias)和可分辨名称(-dname)必须与关联计算机的主机名匹配,否则主机名验证将无法工作。
keytool -genkeypair -alias $(hostname -f) -keyalg RSA -keysize 2048 -dname \ "cn=$(hostname -f)" -keypass password -keystore keystore.jks -storepass password
-
从
keystore
中提取签名的公钥该步骤仅适用于自签名证书
keytool -exportcert -alias $(hostname -f) -keystore keystore.jks -file $(hostname -f).cer -rfc
-
创建包含所有
ZK
实例证书的SSL truststore JKS
同一truststore(存储所有接受的证书)应该在集群的所有成员中共享。 您需要使用不同的别名在同一truststore中存储多个证书,别名的名字无关紧要。
keytool -importcert -alias [host1..3] -file [host1..3].cer -keystore truststore.jks -storepass password
-
向
zoo.cfg
中添加必要配置需要使用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
3.2 不停机升级非TLS
集群
3.5.5 版本新增属性。
以下是利用端口统一功能将已经运行的ZooKeeper集群升级到TLS而不停机所需的步骤:
-
安装上节所述,为每个
ZK
实例创建keystore
和truststore
-
添加以下配置并重启第一个节点,注意
TLS
尚未启用,我们只是对端口进行了统一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
-
重复第二步,并确认日志中可以查看到如下内容:
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
是否恢复正常-
在每个节点上启用
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进行代替。
4.1 四字命令
命令 | 说明 |
---|---|
conf | 3.3.0 版本新增命令。打印服务配置详情。 |
cons | 3.3.0 版本新增命令。列出连接到此服务器的所有客户端的完整连接或会话详细信息。 包括接收或发送的数据包数、 session id 、操作延迟、上次执行的操作等的信息。 |
crst 3.3.0| 3.3.0`版本新增命令。重置所有连接点的连接或会话统计信息。 | |
dump | 列出未完成的会话或临时节点。 |
envi | 打印有关服务环境的详情。 |
ruok | 测试服务端是否允许在非错误状态。 如果服务端正常则响应 imok ,该响应不代表服务端加入了仲裁节点,仅表示服务进程活跃并绑定到指定的客户端端口。要查看仲裁和客户端连接详情请说用 stat 命令。 |
srst | 重置服务端统计信息。 |
srsv | 3.3.0 版本新增命令。列出服务端的完整详细信息。 |
stat | 列出服务端和已连接客户端的简要详情。 |
wchs | 3.3.0`版本新增命令。列出服务端监视的简要信息。 | |
wchc | 3.3.0 版本新增命令。按会话列出服务端监视的详细信息。 会输出会话(连接)列表和关联的监视(路径)。 注意,根据监视点的数量,该操作可能会影响性能,请谨慎使用。 |
dirs | 3.3.0 版本新增命令。展示快照和日志文件总的字节大小。 |
wchp | 3.5.1 版本新增命令。按路径列出有关服务器监视的详细信息。 这将输出具有关联会话的路径( znode )列表。注意,根据监视点的数量,此操作可能会影响服务器性能,请小心使用。 |
mntr | 3.4.0 版本新增命令。输出可用于监视集群运行状况的变量列表。 |
isro | 3.4.0 版本新增命令。测试服务端是否以只读模式允许,如果是响应 ro ,如果不是响应rw 。 |
hash | 3.6.0 版本新增命令。返回与 zxid 关联的树摘要的最新历史记录。 |
gtmk | 将当前跟踪掩码设置为十进制格式的64 位有符号长整形值。有关可能值的说明,请参见 stmk 。 |
stmk | 设置当前跟踪掩码。 跟踪掩码为 64 位,其中每一位启用或禁用服务器上特定类别的跟踪日志记录。必须将 Log4J 配置为首先启用跟踪级别,才能查看跟踪日志记录消息。跟踪掩码的位对应于以下跟踪日志记录类别: 跟踪掩码位的值 跟踪日志记录类别 0b0000000000 未使用,保留供将来使用。0b0000000010 记录除ping 请求外的客户端请求。0b0000000100 未使用,保留供将来使用。0b0000001000 记录客户端ping 请求。0b0000010000 记录从仲裁对等端即当前leader 接收的数据包,不包括ping 请求。0b0000100000 记录客户端会话的添加、删除和验证。0b0001000000 记录将监视事件传递到客户端会话。0b0010000000 记录从仲裁对等端即当前leader 接收的ping 数据包。0b0100000000 未使用,保留供将来使用。0b1000000000 未使用,保留供将来使用。64位值中的所有剩余位都未使用并保留以供将来使用。通过计算记录值的位或,可以指定多个跟踪日志记录类别。 默认跟踪掩码为 0b0100111010 ,因此,默认情况下,跟踪日志记录包括客户机请求、从领导者接收的数据包和会话。要修改跟踪掩码,请发送 stmk 命令后跟64 为长度无符号长整数值的请求到客户端监听端口。 |
4.2 部分示例
-
mntr
示例命令输出格式与Java属性兼容,内容会随着时间推移而改变(比如因为添加了新的key),你的监控脚本也需要随之改变。 展示的有些key是针对特定平台的,有些只会对leader展示。 输出格式为类似以下格式的多行: key1 \t value1 key2 \t value2
$ 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 # 仅向leader曝光 zk_followers 4 # 仅向leader曝光 zk_synced_followers 4 # 仅向leader曝光 zk_pending_syncs 0 #进队Unix平台有效 zk_open_file_descriptor_count 23 #进队Unix平台有效 zk_max_file_descriptor_count 1024
-
ruok
示例echo ruok | nc 127.0.0.1 5111 # imok
-
stmk
示例本例用`Perl`的`pack`函数构造一个跟踪掩码,并附加到`stmk`命令后边,通过`netcat`的`nc`命令发送到服务端的客户端监听端口,服务端响应一个十进制的新跟踪掩码。
perl -e "print 'stmk', pack('q>', 0b0011111010)" | nc localhost 2181 # 250
五、AdminServer
3.5.0中的新功能:AdminServer是一个嵌入式Jetty服务,为四字命令提供HTTP接口。
默认情况下,服务运行在8080端口,命令通过URL形式"/commands/[command name]"发出,如“http://localhost:8080/commands/stat”,
命令返回Json格式的结果。
与原始协议不同,命令可以有多个名称,比如stmk也可以用set_trace_mask,可以通过URL地址"http://localhost:8080/commands"查看所有可用的命令。
AdminServer的端口和URL配置,请参见AdminServer相关的配置选项。
AdminServer默认是启用的,但可用通过以下方式禁用:
1. 设置'zookeeper.admin.enableServer=false';
2. 从类路径中移除Jetty,这对于想要覆盖ZooKeeper的Jetty依赖项很有用。
注意,禁用后四字命令仍然可用。
5.1 可用命令
命令 | 说明 |
---|---|
connection_stat_reset 或crst | 重置所有客户端连接统计信息,没有新字段返回。 |
configuration 或conf 或config | 打印有关服务配置的基本详细信息,例如:客户端端口、数据目录的绝对路径。 |
connections 或cons | 关于服务端上的客户端连接信息,根据连接数量可能会影响性能。 返回 connections ,即客户端的连接对象列表。 |
hash | 历史摘要列表中的Txn 摘要。每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 | 服务端是否是只读模式,返回read_only ,结果true 或false 。 |
last_snapshot 或lsnp | 服务端已完成存储到磁盘的最后一个快照信息,返回zxid 和timestamp ,后者以秒为单位。如果在服务器启动到第一个快照还没有完成保存之前的初始化阶段调用,则将返回启动服务器时读取的快照信息。 |
leader 或lead | 如果集群配置成仲裁模式,则会返回leader 的状态和位置。返回is_leader , leader_id 和 leader_ip 。 |
monitor 或mntr | 发布用于监控的各种有用的信息。 包括性能统计信息、有关内部队列的信息和数据树的摘要(以及其他内容)。 将每个字段作为自己的字段返回。 |
observer_connection_stat_reset 或orst | 重置所有observer 连接统计信息。observer 的伴随指令,不返回新字段。 |
ruok | 无操作的命令,仅检查服务端是否允许。响应并不代表服务端已加入仲裁,仅代表服务端进程活跃且绑定到了指定端口。不返回新的字段。 |
set_trace_mask 或stmk | get_trace_mask 的写入版本,设置跟踪掩码,需要跟一个参数,参见四字命令stmk 的介绍 |
server_stats 或srvr | 服务端信息。返回多个字段,简要概述服务端状态。 |
stats 或stat | 根server_stats 返回相似内容,但是还包括connections 字段。客户端连接数过多可能会影响性能。 |
stat_reset 或srst | 重置服务端统计信息。 是 server_stats 和stats 返回信息的子集,不返回新的字段。 |
observers 或obsr | 与服务端观察者连接相关的信息。 对 leader 总数有用的,对于一个作为leader 备用的follower 也是有用的。返回 synced_observers (int 类型) 和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将其数据存储在数据目录中,将其事务日志存储在事务日志目录中,默认情况下,这两个目录是相同的。
服务器可以(而且应该)配置为将事务日志文件存储在数据文件以外的单独目录中。
当事务日志驻留在专用日志设备上时,吞吐量增加,延迟减少。
6.1 数据目录
该目录包含2到3个文件:
1. myid:内容为人类可读的ASCII文本编码的单个整数,代表服务端ID。
2. initialize:数据树初始化文件,存在则表示缺少数据树,数据树创建后被删除。
3. snapshot:保存数据树的模糊快照。
-
myid
每个ZK服务都有一个唯一的ID,该ID位于myid文件和配置文件中,myid文件标识与给定数据目录相对应的服务端。 配置文件列出了由服务器ID标识的每个服务的连接信息。当ZooKeeper服务启动时,它从myid文件读取ID,并通过ID从配置文件中查找服务应该监听的端口。
-
snapshot
存储在数据目录中的文件时模糊快照,也就是说在ZooKeeper服务拍摄快照期间,数据树正在更新。 快照文件的后缀名是zxid,即快照开始时的最后一个提交的事务的ID。 快照包含在快照处理过程中发生的数据树更新的子集,可能与任何存在的数据树都不对应,因此称之为模糊快照。 ZooKeeper仍然可用使用这个快照进行恢复,因为它利用了更新的幂等性。 通过紧靠模糊快照重新播放事务日志,ZooKeeper可以在日志末尾获得系统的状态。
6.2 日志目录
日志目录包含ZooKeeper的事务日志。
在任何更新之前,ZooKeeper确保表示更新的事务被写入存储器中。
当事务日志数量达到阈值时,将会启动新的日志文件。
阈值是使用影响快照频率的相同参数计算的(请参见上面的snapCount和snapSizeLimitInKb)。
日志文件的后缀是写入该日志的第一个zxid,即第一个写入的事务的ID。
6.3 文件管理
快照和日志文件格式在独立ZooKeeper服务和不同配置的ZooKeeper复制集中不会发生改变。
因此,可用将文件从一个复制集ZooKeeper中拷贝到另一个具有独立ZooKeeper服务的开发机器上进行故障排查。
使用较旧的日志和快照文件,可以查看ZooKeeper服务器以前的状态,甚至可以恢复该状态。
LogFormatter类允许管理员查看日志中的事务。
ZooKeeper服务创建快照和日志文件,但不会删除它们,数据和日志文件的保留策略在ZooKeeper服务之外实现。
ZooKeeper服务本身只需要最新的模糊快照,以及快照之前的最后一个日志文件和之后的所有日志文件。
后一条要求必须包括快照启动后发生的更新,且这些更新以及记录到了现有的日志文件中。
这是可能的,因为快照和日志滚动在ZooKeeper时独立进行的。
有关设置保留策略和ZooKeeper存储维护的详细信息,请参阅本文档中的维护章节。
注意:ZooKeeper文件时未经加密的,在存储敏感数据时,需要采取外部必要措施进行访问权限限制(如控制文件的访问权限),却决于部署时的各中设置。
6.4 恢复TxnLogToolkit
恢复详细信息参见:http://zookeeper.apache.org/doc/current/zookeeperTools.html#zkTxnLogToolkit
七、注意避免事项
以下是通过正确配置ZooKeeper可以避免的一些常见问题:
1. 服务器列表不一致:
客户端使用的服务器列表应该与每个服务端配置的服务器列表一直;如果是服务端配置列表的子集不会出问题,但如果其中一个不在服务端配置的服务器列表中则会出问题。
此外,每个服务端的配置也需要一致。
2. 不当的事务日志存放位置:
事务日志是ZooKeeper最关键的性能部件,在响应前ZooKeeper将事务日志同步到媒介。
专用事务日志设备是保持良好性能的关键,如果将事务日志放到繁忙的存储设备上会产生不利性能影响。
如果只有一个存储设备,则应该增加snapCount以减少快照的生产频率,这并没有解决这个问题带来的影响,但是为事务日志提供了更多的资源。
3. 不当的Java堆大小:
应该特别注意正确配置Java最大堆大小。ZooKeeper任何操作都是有序的,如果处理一个请求使用了交换磁盘,其他请求可能也会这么做,因此不要使用swap。
如果你的机器只有4G内存,不要将Java最大堆大小设置为4G甚至6G,可以设置为3G,因为操作系统和缓存也需要内存。
最好做负载测试来确定远低于会让系统使用到交换内存的使用限制。
4. 可公开访问:
ZooKeeper集群期望运行在可信任的机器环境中,因此最好部署在防护墙后边,而不是直接曝露给公网。
八、最佳实践
为了获得最佳效果,请注意以下Zookeeper的良好做法:
对于多租户安装,请参见ZooKeeper chroot支持章节,
https://zookeeper.apache.org/doc/current/zookeeperProgrammers.html#ch_zkSessions。
这对于将多个应用或服务接口部署在一个ZooKeeper集群中很有用。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。