微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

2021-03-26

Zookeeper 管理文档

一、部署

1.1 系统要求

1.1.1 支持系统平台
ZooKeeper由多个组件组成。
一些组件得到了广泛的支持,而其他组件仅在一组较小的平台上得到支持。
Client是Java客户机库,应用程序使用它连接到ZooKeeper集群。
Server是在ZooKeeper集群节点上运行的Java服务器。
Native Client是用C实现的客户机,类似于Java客户机,由应用程序用来连接到ZooKeeper集群。
Contrib指的是多个可选的附加组件。
1.1.2 支持情况
表格中没有提及的系统,可能支持也可能不支持。对于在没有支持的系统中出现的明显报错,社区会去修复,但没有完全支持
系统/组件ClientServerNative Clientontrib
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 集群设置步骤(每台机器都需要执行)
  1. 安装Java JDK,http://java.sun.com/javase/downloads/index.jsp

  2. 设置Java堆大小,需要正确配置以避免ZooKeeper使用交换内存,如一台4G内存的机器,最大使用3GJava堆大小。

  3. 下载ZooKeeper安装包,http://zookeeper.apache.org/releases.html。

  4. 创建任意文件名的配置文件,一般为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
    
  5. myid文件内容只能是服务器id,如server.1myid内容1,该id必须是唯一的且值介于1-255直接。如果启用如TTL节点等扩展功能,由于内部限制,id必须介于1-254之间。

  6. 在与myid文件相同的目录下创建initialize文件,表示预期的数据目录为空。如果存在,则创建空数据库删除标记文件。如果不存在且数据目录为空,则表示该服务在集群中没有投票权直到数据同步到与leader保持一致,在与leader通信前不会填充数据目录。仅在创建新集群时才创建该文件

  7. 如果配置文件准备完毕,则可以启动服务器:

    $ 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脚本来获取启动示例。
    
    1. 通过连接到主机来测试部署的正确性,Java环境可以通过如下命令来执行简单操作:
    $ bin/zkCli.sh -server 127.0.0.1:2181
    

1.3 单服务和开发环境部署

ZooKeeper入门指南

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服务可以通过以下三种主要方式之一进行监控:
  • 在命令端口上调用四字命令
  • 使用JMX框架,利用jconsole来监控
  • 使用zkServer.sh status命令

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.serverCnxnFactoryzookeeper.clientCnxnSocket作为网络插件时,
自动启用SSL安全连接
observerMasterPort-监听的观察者连接端口,用于故障时候的选举投票
dataDir-存储内存中的数据库快照的位置,如果没有特殊配置dataLogDir还会存储数据库更新的事务日志,
由于ZooKeeper是顺序存取数据到硬盘,配置一个独立的硬盘挂载目录而部署硬盘的某个分区,
有利于得到更好的服务性能
tickTime2000msZooKeeper的最小实际单位,用于设置心跳和超时,单位是毫秒
2.8.2 高级选项
选项认值说明
dataLogDir-指定事务日志写入该指定目录而不是dataDir指定的目录,
便于指定专用的事务日志目录,避免与快照文件资源竞争,
建议将dataLogDirdataDir设置到不同硬盘设备
globalOutstandingLimit1000Java系统属性zookeeper.globalOutstandingLimit.
为了防止排队请求耗尽内存,限制系统中未处理的请求数少于globalOutstandingLimit
preAllocSize64mJava系统属性zookeeper.preAllocSize
为避免ZooKeeperKB为单位预分配事务日志文件空间,
如果频繁创建快照,则应该调小该值,参见snapCountsnapSizeLimitInKb
snapCount10 0000Java系统属性zookeeper.snapCount
ZooKeeper使用快照和事务日志记录其事务,
在快照可以获取前,事务日志中记录的事务数由snapCount确定,
为了避免所有ZooKeeper同时创建快照,
各个ZooKeeper服务中当事务日志中事务数达到[snapCount/2+1,
snapCount]中的某个随机值时,将创建快照
commitLogCount500Java系统属性zookeeper.commitLogCount
ZooKeeper将在内存中维护最后请求的列表,以便于不太落后的followers快速同步,
当快照大于100,000时将显著提高同步性能
snapSizeLimitInKb4194304KB(4GB)Java系统属性zookeeper.snapSizeLimitInKb
ZooKeeper使用快照和事务日志记录其事务,
在可以获取快照(并滚动事务日志)之前,
记录在事务日志中的事务允许的总字节大小由snapSize决定,
为了避免所有ZooKeeper同时创建快照,
各个ZooKeeper服务中当事务日志的字节大小达到
[snapSize/2+1,snapSize]中的某个随机值时,将创建快照,
每个文件系统都有一个最小的标准文件大小,为了有效允许该功能snapSize必须大于该值
txnLogSizeLimitInKb-Java系统属性zookeeper.txnLogSizeLimitInKb
ZooKeeper事务日志可以更直接的用txnLogSizeLimitInKb控制,
因为leader必须扫描磁盘上的日志文件才能找到启动同步的事务,
在事务完成同步时,越大的txn日志将导致follower同步越慢。
认情况下,此功能处于关闭状态,
只有snapCountsnapSizeLimitInKb是限制事务日志大小的值。
如果启用,则事务日志达到限制时将滚动日志,该值如果设置的小于或等于preAllocSize,
可能会导致每个事务都会滚动日志,从而引发性能问题。
为了避免这种情况,建议设置为N * preAllocSize,且N >= 2
maxCnxns0Java系统属性zookeeper.maxCnxns
限制每个ZooKeeper服务的每个客户端端口可建立的并发连接总数,
可以用于抵御某些DOS攻击,认为0,表示没有限制
注意:serverCnxnFactorysecureServerCnxnFactory是分开计数的,
因此如果对等连接是适当的类型,最大允许承载2*maxCnxns个连接数
maxClientCnxns60限制由IP标识的每个客户端可以对集群中ZooKeeper服务进行的socket并发连接数,
用于防御包括文件描述符耗尽在内的某些DOS攻击,设置为0表示没有限制,60
clientPortAddress-3.3.0版本新增属性,侦听客户端连接的地址(IPV4,IPV6、hostname),也就是客户端尝试连接的地址,
该选项可选,认情况下,任何(address/interface/nic)连接到clientPort都将被侦听到
minSessionTimeout2*tickTime3.3.0版本新增属性,服务器允许客户端通过的最小会话超时实际
maxSessionTimeout20*tickTime3.3.0版本新增属性,服务器允许客户端通过的最大会话超时实际
fsync.warningthresholdms1000msJava系统属性zookeeper.fsync.warningthresholdms3.3.4版本新增属性
当事务日志fsync时间超过该值时,就会在log文件中记录一条告警消息。
只能设置为系统属性1000msfsync扩展
maxresponsecacheSize400Java系统属性zookeeper.maxresponsecacheSize
设置为正数,用于确认最近记录的序列化形式缓存的大小,
有助于节省普通Znode的序列化成本。指标response_packet_cache_hits
response_packet_cache_misses有助于将该值调整为给定的工作负载
设置为0将禁用该功能认启用,值为400
maxGetChildrenresponsecacheSize400Java系统属性zookeeper.maxGetChildrenresponsecacheSize
3.6.0版本新增属性
maxresponsecacheSize类似,但适用于获取子请求,
指标response_packet_get_children_cache_hits
response_packet_get_children_cache_misses有助于将该值调整为给定的工作负载
设置为0将禁用该功能认启用,值为400
autopurge.snapRetainCount33.4.0版本新增属性
启用后,ZooKeeper自动保留dataDirdataLogDir中与autopurge.snapRetainCount相同数量的最新的快照和事务日志,
删除其他的快照和事务日志。最小值33
autopurge.purgeInterval03.4.0版本新增属性
自动清除任务触发的时间间隔(单位:小时),设置为1及以上自动触发,0
syncEnabledtrueJava系统属性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选举,连续两次通知检查间的时间长度上限
connectionMaxTokens0Java系统属性zookeeper.connection_throttle_tokens
3.6.0版本新增属性,这是调整服务器端连接节流器的参数之一,
它是一种基于令牌的速率限制机制,具有可选的概率丢弃。
此参数定义令牌桶中的最大令牌数。设置为0时,将禁用限制。认值为0
connectionTokenFillTime1Java系统属性zookeeper.connection_throttle_fill_time
3.6.0版本新增属性,这是优化服务器端连接节流器的参数之一,
它是一种基于令牌的速率限制机制,具有可选的概率丢弃。
此参数定义用connectionTokenFillCount令牌重新填充令牌桶的时间间隔(以毫秒为单位)。认值为1
connectionTokenFillCount1Java系统属性zookeeper.connection_throttle_fill_count
3.6.0版本新增属性,这是优化服务器端连接节流器的参数之一,
它是一种基于令牌的速率限制机制,具有可选的概率丢弃。
此参数定义每隔connectionTokenFillTime时间添加到令牌桶的令牌数,1
connectionFreezeTime-1Java系统属性zookeeper.connection_throttle_freeze_time
3.6.0版本新增属性,这是调整服务器端连接节流器的参数之一,
它是一种基于令牌的速率限制机制,具有可选的概率丢弃。
此参数定义调整丢弃概率时的间隔(毫秒)。
设置为-1时,禁用概率丢弃。认值为-1
connectionDropIncrease0.02Java系统属性zookeeper.connection_throttle_drop_increase
3.6.0版本新增属性,这是调整服务器端连接节流器的参数之一,
它是一种基于令牌的速率限制机制,具有可选的概率丢弃。
此参数定义每次要增加的丢弃概率,
节流器每隔connectionFreezeTime检查一次,
如果令牌桶为空,则丢弃概率增加connectionDropIncrease
connectionDropDecrease0.002Java系统属性zookeeper.connection_throttle_drop_decrease
3.6.0版本新增属性,这是调整服务器端连接节流器的参数之一,
它是一种基于令牌的速率限制机制,具有可选的概率丢弃。
此参数定义每次要降低的丢弃概率,
节流器每隔connectionFreezeTime检查一次,
如果令牌桶超过阈值,则丢弃概率降低connectionDropDecrease
阈值=connectionMaxTokens * connectionDecreaseRatio
connectionDecreaseRatioJava系统属性zookeeper.connection_throttle_decrease_ratio
3.6.0版本新增属性,这是调整服务器端连接节流器的参数之一,
它是一种基于令牌的速率限制机制,具有可选的概率丢弃。
此参数定义了降低丢弃概率的阈值。认值为0。
zookeeper.connection_throttle_weight_enabledfalse只有Java系统属性3.6.0版本新增属性,节流时是否考虑连接权重。
仅当启用连接限制时有用,也就是connectionMaxTokens大于0false
zookeeper.connection_throttle_global_session_weight3只有Java系统属性3.6.0版本新增属性,全局会话的权重,它是全局会话请求通过连接节流器所需的令牌数。
它必须是不小于本地会话权重的正整数。认值为3
zookeeper.connection_throttle_local_session_weight1只有Java系统属性3.6.0版本新增属性,它是本地会话请求通过连接节流器所需的令牌数。
它必须是不大于全局会话或续订会话的权重的正整数。认值为1
zookeeper.connection_throttle_renew_session_weight2只有Java系统属性3.6.0版本新增属性,重新开始一个会话的权重。它也是重新连接请求通过节流器所需的令牌数。
它必须是不小于本地会话权重的正整数。认值为2。
clientPortListenBacklog503.4.14, 3.5.5, 3.6.0版本新增属性ZooKeeper服务socket连接的套接字积压长度,这控制将在服务器端排队等待ZooKeeper服务处理的请求数。
超过该长度将会收到30s网络超时,可能会导致会话过期,-1表示禁用,linux50个积压。
serverCnxnFactoryNIOServerCnxnFactoryJava系统属性zookeeper.serverCnxnFactory
指定serverCnxnFactory方式,
设置为NettyServerCnxnFactory以便使用基于TLS的通信服务,NIOServerCnxnFactory
flushDelay0Java系统属性zookeeper.flushDelay
延迟刷新日志的时间(单位:毫秒),
不影响maxBatchSize定义的限制,
0表示禁用,具有高写入速率的集群设置为10-20ms
maxWriteQueuePollTimeflushDelay/3Java系统属性zookeeper.maxWriteQueuePollTime
如何flushDelay启用,则表示如果没有新的请求,
在刷新日志前等待时间,flushDelay/3
maxBatchSize1000Java系统属性zookeeper.maxBatchSize
触发刷新日志前服务中允许的事务数量,不影响flushDelay定义的限制,1000
requestThrottleLimit0Java系统属性
zookeeper.request_throttle_max_requests3.6.0版本新增属性
RequestThrottler着手暂停前允许的最大重要请求数,0表示没有限制。
requestThrottleStallTime100Java系统属性zookeeper.request_throttle_stall_time3.6.0版本新增属性,最大线程等待时间(单位:毫秒)
requestThrottleDropStaletrueJava系统属性request_throttle_drop_stale
3.6.0版本新增属性,如果启用,节流器将丢弃过时请求,而不是将他们发送到请求管道。
过时请求可能是现在已关闭的连接发送的请求或超过sessionTimeout的请求。
requestStaleLatencyCheckfalseJava系统属性zookeeper.request_stale_latency_check3.6.0版本新增属性,启用时如果请求延迟比关联会话超时时间高则任务请求过时,认禁用
requestStaleConnectionChecktrueJava系统属性
zookeeper.request_stale_connection_check
3.6.0版本新增属性
启用时如果请求连接已经关闭则任务请求过时,认启用
zookeeper.request_throttler.shutdownTimeout10000只有Java系统属性3.6.0版本新增属性RequestThrottler在请求队列强制关闭之前等待请求队列在关闭期间耗尽的时间(单位:毫秒),认值为10000
advancedFlowControlEnabled-Java系统属性
zookeeper.netty.advancedFlowControl.enabled,根据ZooKeeper管道的状况,在网络中采用精确的流量控制,避免直接缓冲。它将在Netty中禁用AUTO_READ
enableEagerACLCheckfalseJava系统属性zookeeper.enableEagerACLCheck,如果设置为true,在将请求发送给仲裁之前,将会为每个本地服务的写请求启用ACL检查,false
maxConcurrentSnapSyncs10Java系统属性
zookeeper.leader.maxConcurrentSnapSyncs
单个leaderfollower可以同时服务的最大快照同步数,10
maxConcurrentDiffSyncs100Java系统属性
zookeeper.leader.maxConcurrentDiffSyncs,单个leaderfollower可以同时服务的最大差异同步数,100
digest.enabledfalseJava系统属性zookeeper.digest.enabled3.6.0版本新增属性
‎在从磁盘加载数据库、追赶和跟踪leader时,添加摘要功能以检测ZooKeeper 内部的数据不一致性,它根据报告中提到的 adHashDataTree进行增量哈希检查‎。
其思想很简单,DataTree的哈希值将根据数据集的变化进行增量更新。leader在准备txn时,会根据公式发生的变化预先计算树的哈希值:
current_hash = current_hash + hash(new node data) - hash(old node data)
如果是创建新节点,旧节点数据的哈希值将为0,
如果是删除节点操作,新节点数据的哈希值将为0。
‎此哈希值将与每个txn关联,以表示将txn应用到数据树后的预期哈希值,它将被发送给具有原始建议的followerleader将在将 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,但启用了followerfollower将获得EOF异常,该异常将被优雅地处理。
注意:当前摘要计算排除了/zookeeper下的节点,因为/zookeeper/quota 节点中存在潜在的不一致性,我们可以在修复该问题之后包含该节点。
认情况下,此功能已禁用,请设置true以启用它。
snapshot.trust.emptyfalseJava系统属性zookeeper.snapshot.trust.empty3.5.6版本新增属性
属性控制ZooKeeper是否应将丢失的快照文件视为无法从中恢复的致命状态,设置为true以允许ZooKeeper服务在没有快照文件的情况下恢复。
只有在从ZooKeeper的旧版本(3.4.x3.5.3之前)升级时才应设置此选项,其中ZooKeeper可能只有事务日志文件,但不存在快照文件
如果在升级过程中设置了该值,建议升级后将值设置为false,然后重新启动ZooKeeper进程,以便ZooKeeper在恢复过程中继续正常的数据一致性检查。认值为false
audit.enablefalseJava系统属性zookeeper.audit.enable3.6.0版本新增属性认情况下,将禁用审计日志。设置为true以启用它。认值为false。有关详细信息,请参阅ZooKeeper审计日志
audit.impl.classJava系统属性zookeeper.audit.impl.class3.6.0版本新增属性,审计记录器的实现类,认情况下log4j继承自org.apache.zookeeper.audit .Log4jAuditLogger审计记录器。有关详细信息,请参阅ZooKeeper审计日志
largeRequestMaxBytes1024*1024*1024Java系统属性zookeeper.largeRequestMaxBytes3.6.0版本新增属性
即将达到的请求的最大字节数,如果超过限制将被关闭1024*1024*1024
largeRequestThreshold*-1Java系统属性zookeeper.largeRequestThreshold3.6.0版本新增属性
将请求视为大请求的阈值,-1表示将所有请求都视为小请求。
outstandingHandshake.limit-只有Java系统属性
zookeeper.netty.server.outstandingHandshake.limit
在请求途中的最大TLS连接数,超过限制将在握手前被拒绝。
属性不会限制最大TLS并发数,但有助于避免请求途中的TLS握手过多时由于TLS握手超时导致的羊群效应,设置为250可以有效避免羊群效应。
2.8.3 集群选项
选项认值说明
electionAlg31:基于UDP的非身份验证版本的快速leader选举;
2:基于UDP的身份验证版本的快速leader选举;
3:基于TCP版本的快速leader选举。
3.2.0版本认用的3,之前也用的12
3.4.0版本中12被启用,3.6.0版本后由于只提供FastleaderElection,因此升级时必须关闭所有服务,并设置electionAlg=3,或删除改行设置。
initLimit-允许follower连接并同步leader的时间量,单位为tickTime
如果ZooKeeper管理数量很大,则需要适当增加该值。
connectToLearnerMasterLimitJava系统属性zookeeper.connectToLearnerMasterLimitleader选举后follower连接到leader的时间,认为initLimit的值,当initLimit很高时使用,这样连接到leader不会导致更高的超时。
leaderServesyesJava系统属性zookeeper.leaderServesleader机器允许客户端连接,yesleader机器协调更新,为了获取更高的更新吞吐量可以设置不接受客户机连接稍微牺牲读取吞吐量,以将重点放在协调上。
当前集群中由三个以上服务端时候,建议启用。
server.x=[hostname]:nnnnn[:nnnnn] etc-组成ZooKeeper集群的服务器。
当服务启动后,将会通过查看数据目录下的myid文件确认是集群中的哪个服务,文件中包含了与server.xx对应的服务器的ASCII编码。
ZooKeeper集群中每个服务器配置中的服务器列表必须有对应开启的ZooKeeper服务。
两个nnnnn代表端口号,第一个用于连接leader,第二个用于leader选举,如果是一台服务器上模拟集群,可以通过不同端口来区分。
ZooKeeper 3.6.0版本后可以为每个ZooKeeper服务器指定多个地址,详见ZOOKEEPER-3188,如果要开启该功能,需要设置multiAddress.enabledtrue,多地址有助于增强可用性和网络恢复能力。当服务器使用多个物理网络接口时,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-允许followerleader同步应答的tick数(tickTime的倍数),如果follower远远落后于leader则将被丢弃
group.x=nnnnn[:nnnnn]启用分级仲裁结构,x表示组标识符,=号后边的数字nnnnn代表服务器标识符,服务器标识符间用冒号:分隔;组与组之间必须没有交集,并且所有组的并集为一个ZooKeeper集群。
weight.x=nnnnn1group一起使用,在仲裁时分配权重,x为组标识符。
ZooKeeper有几个部分需要投票,比如领导人选举和原子广播协议。
认情况下所有服务器的权重都是1,如果配置只定义了组但没有分配权重,则所有服务器的权重都是1
你可以从这里查看例子
cnxTimeout5sJava系统属性zookeeper.cnxTimeout
设置leader选举时,打开连接的超时时间,仅适用于electionAlg=3的情况,5s
quorumCnxnTimeoutMs-1Java系统属性zookeeper.quorumCnxnTimeoutMs,设置leader选举时,从连接读取的超时时间,仅适用于electionAlg=3的情况,认是-1,表示使用synclimit * tickTime作为超时时间
standaloneEnabledtrue3.5.0版本新增属性,当设置为false时,单节点可以以replicated复制模式允许,单个参与者可以与观察者一起运行,集群可以向下配置到一个新节点,并从一个节点向上配置。
为了向后兼容,认为true
可以使用QuorumPeerConfigsetStandaloneEnabled方法或在服务配置中指定standaloneEnabled=false|true来设置它。
reconfigEnabledfalse3.5.3版本新增属性,控制动态配置功能的开启或禁用。
如果启用,有权限的用户可以通过客户端或API进行动态修改配置。
如果禁用,包括超级用户在内的所有用户都无权进行动态修改配置,如果操作就会报错。
可以使用QuorumPeerConfigsetReconfigEnabled方法或在服务配置中指定reconfigEnabled=false|true来设置它,false
集群中所有服务器的该值应该保持一致,如果不同会导致服务器间出现不一致情况。
如果leader设置为true则集群将启用该功能,反之禁用,如果发生了重新选举,则可能导致出现结果与预期不符。
4lw.commands.whitelistsrvrJava系统属性zookeeper.4lw.commands.whitelist3.5.3版本新增属性,逗号分隔的ZooKeeper四字命令白名单,名单类的命令用户才可以使用。
认情况下白名单只包括srvr命令共zkServer.sh使用,配置示例如下:
4lw.commands.whitelist=stat, ruok, conf, isro
如果想要启用所有四字命令,可以用*星号指代所有:
4lw.commands.whitelist=*
tcpKeepAlivefalseJava系统属性zookeeper.tcpKeepAlive3.5.4版本新增属性,设置为true表示在集群成员间选举的socket套接字上加上TCP KeepAlive标志,使成员间可以保持长连接。
长时间的空闲连接,可能会导致某些NAT或防火墙终止或失去状态。
该设置依赖于操作系统的KeepAlive设置,false
electionPortBindRetry3Java系统属性zookeeper.electionPortBindRetryZooKeeper服务连接leader选举端口失败的重连次数认是3,如果是容器特别是K8S环境中,则应该设置为0,表示尝试无限次或增加尝试次数,以克服DNS解析方面的问题。
observer.reconnectDelayMs0msJava系统属性zookeeper.observer.reconnectDelayMs,尝试重连的间隔时间,0ms
observer.election.DelayMs200msJava系统属性zookeeper.observer.election.DelayMs,‎在断开连接后延迟观察员参加leader选举,以防止投票同行在这个过程中意外增加负担。‎200ms
localSessionsEnabledlocalSessionsUpgradingEnabledfalse3.5.0版本新增属性,可选值trUefalse认都是false
localSessionsEnabled=true开启本地会话,
localSessionsUpgradingEnabled=true按需将本地会话升级为全局会话,
需要同时开启localSessionsEnabled
2.8.4 加密、身份验证和授权选项
选项认值说明
DigestAuthenticationProvider.superDigestfalseJava系统属性zookeeper.DigestAuthenticationProvider.superDigest3.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.X509KeyManagerjavax.net.ssl.x509trustmanager以从SSL堆栈中获取所期性能是必要的。要使用自定义的身份验证程序,请为自定义程序选定scheme方案名,并设置zookeeper.ssl.authProvider=[scheme],这样才能把自定义程序加载到ProviderRegistry中,并使用它进行身份验证。
zookeeper.ensembleAuthName-Java系统属性zookeeper.ensembleAuthName3.6.0版本新增属性,以逗号分隔的集群的有效名称或别名列表。客户端可以提供想要连接的集群名称作为集群方案的凭证。EnsembleAuthenticationProvider将对照列表验证客户端提供的凭据以接收请求,如果凭据不在列表中,则被拒绝连接,可以防止客户端连接到错误的集群中。
zookeeper.sessionRequireClientSASLAuthfalseJava系统属性zookeeper.sessionRequireClientSASLAuth3.6.0版本新增属性,设置为true,服务端将只接收通过SASL了身份验证的客户端的请求和连接。未配置SASL身份验证或配置SASL但身份验证失败(即凭据无效)的客户端将无法与服务器建立会话。产生错误代码-124,这种情况下JavaC客户端将关闭与服务端的会话,并不再尝试重连。false。该属性否定了zookeeper.allowSaslFailedClients属性,所以即便设置了允许SASL身份验证失败的客户端登录,客户端也无法与服务端建立会话。
sslQuorumfalseJava系统属性zookeeper.sslQuorum3.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.password3.5.5版本新增属性
指定Java密钥库的文件路径,包括客户端和仲裁TLS连接证书和对应用于解锁文件密码
ssl.keyStore.type
ssl.quorum.keyStore.type
nullJava系统属性zookeeper.ssl.keyStore.type
zookeeper.ssl.quorum.keyStore.type3.5.5版本新增属性,指定证书和密钥文件格式,可选值有JKS,PEM, PKCS12nullnull表示根据文件名自行检测)
ssl.trustStore.location
ssl.trustStore.password
ssl.quorum.trustStore.locationssl.quorum.trustStore.password
Java系统属性zookeeper.ssl.trustStore.location
zookeeper.ssl.trustStore.password
zookeeper.ssl.quorum.trustStore.location
zookeeper.ssl.quorum.trustStore.password3.5.5版本新增属性
指定Java信任库的文件路径,该信任库包含用于客户端和仲裁TLS连接的远程凭据,以及用于解锁文件密码
ssl.trustStore.typessl.quorum.trustStore.typenull |Java系统属性:**zookeeper.ssl.trustStore.type** 和**zookeeper.ssl.quorum.trustStore.type**,3.5.5版本新增属性,指定客户端和仲裁信任库的文件格式,可选值有JKS, PEM,PKCS12nullnull`表示根据文件名自行检测)
ssl.protocolssl.quorum.protocolTLSv1.2Java系统属性zookeeper.ssl.protocolzookeeper.ssl.quorum.protocol3.5.5版本新增属性,指定要在客户端和仲裁TLS协商中使用的协议。
ssl.enabledProtocolsssl.quorum.enabledProtocolsTLSv1.2Java系统属性zookeeper.ssl.enabledProtocolszookeeper.ssl.quorum.enabledProtocols3.5.5版本新增属性,指定客户端和Quorum TLS协商中启用的协议。认为protocol属性的值。
ssl.ciphersuitesssl.quorum.ciphersuitesJava系统属性zookeeper.ssl.ciphersuiteszookeeper.ssl.quorum.ciphersuites3.5.5版本新增属性,指定要在客户端和仲裁TLS协商中使用的密码套件,取决于Java运行时版本。
ssl.context.supplier.class
ssl.quorum.context.supplier.class
nullJava系统属性zookeeper.ssl.context.supplier.classzookeeper.ssl.quorum.context.supplier.class3.5.5版本新增属性,指定用于在客户端和仲裁SSL通信中创建SSL上下文的类,这允许您使用自定义SSL上下文并实现以下场景:
1. 使用硬件密钥库,使用PKCS11或类似的东西加载。
2.您无权访问软件密钥库,但可以从其容器中检索已构建的SSLContext
认值:null
ssl.hostnameVerification
ssl.quorum.hostnameVerification
trueJava系统属性zookeeper.ssl.hostnameVerificationzookeeper.ssl.quorum.hostnameVerification3.5.5版本新增属性,指定是否在客户端和仲裁TLS协商过程中启用hostname验证。禁用它仅建议用于测试目的。认值:true
ssl.crlssl.quorum.crlfalseJava系统属性zookeeper.ssl.crlzookeeper.ssl.quorum.crl3.5.5版本新增属性,指定是否在客户端和仲裁TLS协议中启用证书吊销列表。认值:false
ssl.ocspssl.quorum.ocspfalseJava系统属性zookeeper.ssl.ocspzookeeper.ssl.quorum.ocsp3.5.5版本新增属性,指定客户端和仲裁TLS协议中是否启用联机证书状态协议。认值:false
ssl.clientAuthssl.quorum.clientAuthneedJava系统属性zookeeper.ssl.clientAuthzookeeper.ssl.quorum.clientAuth3.5.5版本新增属性,在3.5.7版本终止。指定用于验证来自客户端的ssl连接的选项,有效值如下:
none:服务端不请求客户端身份验证,
want:服务端将会请求客户端身份验证,
need:服务端将要求客户端身份验证。
ssl.handshakeDetectionTimeoutMillis
ssl.quorum.handshakeDetectionTimeoutMillis
-Java系统属性zookeeper.ssl.handshakeDetectionTimeoutMilliszookeeper.ssl.quorum.handshakeDetectionTimeoutMillis3.5.5版本新增属性,待定。
client.portUnificationfalseJava系统属性zookeeper.client.portUnification,指定客户端端口必须接收SSL全连接(与客户端安全连接端口配置相同),false
authProvider-Java系统属性zookeeper.authProvider),可以指定多个身份验证程序类,通常用于指定多个SASL身份验证提供程序类,如:
authProvider.1=org.apache.zookeeper.server.auth.SASLAuthenticationProvider
kerberos.removeHostFromPrincipalfalseJava系统属性zookeeper.kerberos.removeHostFromPrincipal,你可以指示ZooKeeper在验证期间从客户机主体中删除主机,如将zk/[email protected]验证为[email protected]
kerberos.removeRealmFromPrincipalJava系统属性zookeeper.kerberos.removeRealmFromPrincipal,你可以指示ZooKeeper在验证期间从客户机主体中删除域,如将zk/[email protected]验证为zk/hostname
multiAddress.enabledfalseJava系统属性zookeeper.multiAddress.enabled3.6.0版本新增属性
启用该功能可以为ZooKeeper服务指定多个地址以提高可用性,如果集群中有3.6.0以前的旧版本,则不支持升级期间启用该功能false
multiAddress.reachabilityCheckTimeoutMsJava系统属性zookeeper.multiAddress.reachabilityCheckTimeoutMs3.6.0版本新增属性ZooKeeper将执行ICMP ECHO请求或尝试在目标主机的TCP端口7上建立连接(Echo),以便找到可以访问的地址。
属性设置可达性检查的超时时间,多个地址检查是并发执行的,因此该值为最长超时时间。必须启用multiAddress.enabled才有效。
2.8.5 实验选项/特性
选项认值说明
Read Only Mode ServerfalseJava系统属性readonlymode.enabled3.4.0版本新增属性
设置为true,服务器将启用只读模式(ROM),false
启用ROM将允许客户端连接到支持ROM服务,即使服务已经从仲裁中分离,
这种模式下客户端仍然可以从ZK服务中读取值,但不能写入值和看到其他客户端的变化。
2.8.6 不安全选项
选项认值说明
forceSync-Java系统属性zookeeper.forceSync3.4.0版本新增属性,设置为yes,要求更新完成前将内容同步更新到事务日志媒介,设置为no则与之相反。
jute.maxbuffer0xFFFFFFJava系统属性jute.maxbuffer
‎此选项只能设置为 Java 系统属性‎,不带zookeeper前缀。指定znode中可以存储的最大数据大小,单位字节,0xFFFFFF(1048575)字节,略低于1M
如果要更改该属性,必须在所有服务端和客户端上设置,否则会出现问题;
如果客户端的该值大于服务端的该值,客户端写入数据时服务端会报错java.io.IOException: Len error
如果客户端的该值小于服务端的该值,客户端读取该值长度的数据时,客户端将会报错java.io.IOException: Unreasonable lengthPacket len is out of range!
生产环境中因为以下原因不建议将该值增加到超过认值:
1. 大尺寸的znode会导致不必要的延迟峰值,降低吞吐量。
2. 大尺寸的znode会导致leaderfollower间的同步不可预测且不收敛(有时候会超时),从而导致仲裁不稳定。
jute.maxbuffer.extrasize-Java系统属性zookeeper.jute.maxbuffer.extrasize3.5.7版本新增属性,在处理客户端请求时,在事务持久化前,ZooKeeper会在请求中添加一些附加信息。在此之前,该值固定为1024字节,对于许多场景,特别是jute.maxbuffer的值大于1M且请求类型为multi时,固定值是不足的;
为了应对所有常见,将该值从固定值1024增加jute.maxbuffer大小,也可以通过jute.maxbuffer.extrasize直接配置。
通常不需要更改,因为认就是最佳值。
skipACL-Java系统属性zookeeper.skipACL,跳过ACL检查,这可以调高吞吐量,但是会给予用户对数据数的完整访问权限。
quorumListenOnAllIPsfalse如果设置为trueZooKeeper服务端将会从所有可用的IP地址侦听其对等方的连接,而不仅仅是配置文件配置的服务器列表中配置的地址。会影响处理ZAB协议和快速leader选举协议的连接。
multiAddress.reachabilityCheckEnabledtrueJava系统属性zookeeper.multiAddress.reachabilityCheckEnabled3.6.0版本新增属性,从3.6.0版本开始,,ZooKeeper将执行ICMP ECHO请求或尝试在目标主机的TCP端口7上建立连接(Echo),以便找到可以访问的地址。
只有配置了多个地址才会发生,当你尝试在一台机器上启用多个成员的集群(如11+),如果达到了某些ICMP速率限制,可达性检查可能会失败。
设置为false可用禁用可达性检查,true,禁用可达性检查会导致集群在出现网络故障时无法正确的调整,因此仅建议在测试期间禁用可达性检查。
仅在设置了multiAddress.enabled=true时才有效。
2.8.7 禁用数据目录自动创建
选项认值说明
datadir.autocreatefalse3.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.numSelectorThreadssqrt(sum(cpu)/2)只有Java系统属性zookeeper.nio.numSelectorThreads,'3.5.0’版本新增属性NIO选择器线程的数量,最少1个,建议多个。
认值是sqrt(sum(cpu)/2),即cpu个数的一半的平方根。
zookeeper.nio.numWorkerThreads2*sum(cpu)只有Java系统属性zookeeper.nio.numWorkerThreads,'3.5.0’版本新增属性NIO工作线程的数量,如果设置为0,则选择器线程直接执行套接I/O认是cpu核心数的两倍。
zookeeper.commitProcessor.numWorkerThreads1*sum(cpu)只有Java系统属性
zookeeper.commitProcessor.numWorkerThreads,'3.5.0’版本新增属性Commit Processor工作线程的数量,如果设置为0,则主线程将直接处理请求,认值是cpu的核心数。
zookeeper.commitProcessor.maxReadBatchSize1*sum(cpu)只有Java系统属性
zookeeper.commitProcessor.maxReadBatchSize
在切换到处理请求前,从等待处理的请求队列中处理的最大读取数。
如果值小于0认),则每当有本地写入或等待的提交时都会进行切换。较高的读取批大小,将会延迟提交处理,从而导致提供过时数据。
如果已知读取以固定大小批的形式到达,那么将该批大小与该属性的值匹配可以平滑队列性能
由于读取是并行处理的,建议将值设置为匹配zookeeper.commitProcessor.numWorkerThread认为cpu核心数)或更低。
zookeeper.commitProcessor.maxCommitBatchSize1只有Java系统属性
zookeeper.commitProcessor.maxCommitBatchSize
处理读请求前处理的最大提交数。我们将会处理尽可能多的远程或本地提交数,直到达到该计数。高提交批大小将在处理更多提交时,延迟读取,低提交批大小将有利于读取。
建议仅在集群提供高提交率的工作负载服务时设置该值。
如果已知写入以一定数量的批到达,则将该批大小与此属性的值匹配可以平滑队列性能
‎一般方法是将此值设置为等于集群大小,以便当前服务器在处理每批时能够概率处理与其直连的客户之一相关的写入‎。
1不支持负值和0值。
znode.container.checkIntervalMs60,000只有Java系统属性3.6.0版本新增。
候选容器和TTL节点每次检查的时间间隔,单位毫秒。
znode.container.maxPerMinute10000只有Java系统属性3.6.0版本新增。
每分钟可删除的最大容器和ttl节点数。
这样可以防止在删除容器时出现羊群现象。
认值为10000
znode.container.maxNeverUsedIntervalMs0只有Java系统属性3.6.0版本新增。
从未包含任何子级的容器的保留时间,单位毫秒。
需要设置的足够长,以便客户端创建容器,执行任何需要的工作以及创建子级。
0,表示不会删除从未包含任何子级的容器。
2.8.10 调试可观察性配置
从'3.6.0'版本开始,为了更易于调试,增加了以下选项。
选项认值说明
zookeeper.messageTracker.BufferSize10只有Java系统属性,控制存储在MessageTracker中的最大消息数。
值必须是正数,认是10
MessageTracker3.6.0引入的,用于记录服务器(包括followerobserver)与leader间断开连接时的最后一组消息。
这些消息将被转存到ZooKeeper的日志文件中,有助于重建断开连接时服务器的状态,对调试非常有用。
zookeeper.messageTracker.Enabledfalse只有Java系统属性,设置为true,将会启用MessageTracker来跟踪和记录消息。
2.8.11 AdminServer`配置
选项认值说明
admin.portUnificationfalseJava属性zookeeper.admin.portUnification3.6.0版本新增,
启用管理端口,接受HTTPHTTPS通信,认不启用。
admin.enableServertrueJava属性zookeeper.admin.enableServer3.5.0版本新增,
设置为false禁用AdminServer认时启用的
admin.serverAddress0.0.0.0Java属性zookeeper.admin.serverAddress3.5.0版本新增,
嵌入式Jetty服务器侦听的地址。认为0.0.0.0
admin.serverPort8080Java属性zookeeper.admin.serverPort3.5.0版本新增,嵌入式Jetty服务器侦听的端口。认为8080
admin.idleTimeout30,000Java属性zookeeper.admin.idleTimeout3.5.0版本新增,
设置一个连接在接收和发送数据前可用等待的最大空闲时间,单位毫秒
admin.commandURL/commandsJava属性zookeeper.admin.commandURL3.5.0版本新增,用于列出和发送命令的相对于根URLURL地址,/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.httpPort7000Prometheus.io将会启用一个Jetty服务并绑定到该端口,认时7000
Prometheus.io站点http://hostname:httPort/metrics
metricsProvider.exportJvmInfotrue如果设置为truePrometheus.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而不停机所需的步骤:
  1. 安装上节所述,为每个ZK实例创建keystoretruststore

  2. 添加以下配置并重启第一个节点,注意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
    
  3. 重复第二步,并确认日志中可以查看到如下内容

    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
    
  4. 再次确认每个节点重启后查看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 四字命令

命令说明
conf3.3.0 版本新增命令。
打印服务配置详情。
cons3.3.0 版本新增命令。
列出连接到此服务器的所有客户端的完整连接或会话详细信息。
包括接收或发送的数据包数、session id、操作延迟、上次执行的操作等的信息。
crst3.3.0|3.3.0`版本新增命令。
重置所有连接点的连接或会话统计信息。
dump列出未完成的会话或临时节点。
envi打印有关服务环境的详情。
ruok测试服务端是否允许在非错误状态。
如果服务端正常则响应imok,该响应不代表服务端加入了仲裁节点,仅表示服务进程活跃并绑定到指定的客户端端口。
要查看仲裁和客户端连接详情请说用stat命令。
srst重置服务端统计信息。
srsv3.3.0版本新增命令。
列出服务端的完整详细信息。
stat列出服务端和已连接客户端的简要详情。
wchs |3.3.0`版本新增命令。
列出服务端监视的简要信息。
wchc3.3.0版本新增命令。
按会话列出服务端监视的详细信息。
输出会话(连接)列表和关联的监视(路径)。
注意,根据监视点的数量,该操作可能会影响性能,请谨慎使用。
dirs3.3.0版本新增命令。
展示快照和日志文件总的字节大小。
wchp3.5.1版本新增命令。
按路径列出有关服务器监视的详细信息。
这将输出具有关联会话的路径(znode)列表。
注意,根据监视点的数量,此操作可能会影响服务器性能,请小心使用。
mntr3.4.0版本新增命令。
输出可用于监视集群运行状况的变量列表。
isro3.4.0版本新增命令。
测试服务端是否以只读模式允许,如果是响应ro,如果不是响应rw
hash3.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_resetcrst重置所有客户端连接统计信息,没有新字段返回。
configurationconfconfig打印有关服务配置的基本详细信息,例如:客户端端口、数据目录的绝对路径
connectionscons关于服务端上的客户端连接信息,根据连接数量可能会影响性能
返回connections,即客户端的连接对象列表。
hash历史摘要列表中的Txn摘要。每128个事务记录一笔。
返回digests,即事务摘要对象的列表。
dirs日志文件目录和快照目录的字节大小信息,返回datadir_sizelogdir_size
dump有关过期和临时会话的信息。根据过期和临时会话数量,可能会影响性能
以映射形式返回expiry_time_to_session_idssession_id_to_ephemeral_paths
environmentenvenvi所有定义的环境变量,将每个字段当作自己的字段返回。
get_trace_maskgtmk当前跟踪掩码,set_trace_mask的只读形式,详解stmk的描述,返回tracemask
initial_configurationicfg打印启动连接的基础配置的内容,返回initial_configuration
is_read_onlyisro服务端是否是只读模式,返回read_only,结果truefalse
last_snapshotlsnp服务端已完成存储到磁盘的最后一个快照信息,返回zxidtimestamp,后者以秒为单位。如果在服务器启动到第一个快照还没有完成保存之前的初始化阶段调用,则将返回启动服务器时读取的快照信息。
leaderlead如果集群配置成仲裁模式,则会返回leader的状态和位置。返回is_leader, leader_idleader_ip
monitormntr‎发布用于监控的各种有用的信息。‎
包括性能统计信息、有关内部队列的信息和数据树的摘要(以及其他内容)。
将每个字段作为自己的字段返回。
observer_connection_stat_resetorst重置所有observer连接统计信息。observer的伴随指令,不返回新字段。
ruok无操作的命令,仅检查服务端是否允许。响应并不代表服务端已加入仲裁,仅代表服务端进程活跃且绑定到了指定端口。不返回新的字段。
set_trace_maskstmkget_trace_mask的写入版本,设置跟踪掩码,需要跟一个参数,参见四字命令stmk的介绍
server_statssrvr服务端信息。返回多个字段,简要概述服务端状态。
statsstatserver_stats返回相似内容,但是还包括connections字段。客户端连接数过多可能会影响性能
stat_resetsrst重置服务端统计信息。
server_statsstats返回信息的子集,不返回新的字段。
observersobsr与服务端观察者连接相关的信息。
leader总数有用的,对于一个作为leader备用的follower也是有用的。
返回synced_observers(int类型) 和observers(每个观察者属性的列表)。
system_propertiessysp所有定义的系统属性。将每个字段作为自己的字段返回。
voting_view提供集合中当前有投票权的成员。以映射形式返回current_config字段。
watcheswchc监视会话聚合的信息,根据会话数量可能会影响性能
以映射形式返回session_id_to_watched_paths字段
watches_by_pathwchp监视路径聚合的信息,根据路径数量可能会影响性能
以映射形式返回path_to_session_ids字段
watch_summarywchs监视摘要信息。返回"num_total_watches, num_pathsnum_connections字段。
zabstate对等机的Zab协议运行阶段以及是否有投票权。
对等机可以处于以下阶段之一:ELECTION, disCOVERY,SYNCHRONIZATION, broADCAST
返回votingzabstate字段

六、数据文件管理

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] 举报,一经查实,本站将立刻删除。

相关推荐