赞
踩
翻译自ZK官网, 部分有省略
原文
需要Java 8 或者以上 (JDK8 LTS, JDK 11 LTS, JDK12. JDK9 和 10 不支持). 服务端要组成集群的话, 至少要3个独立的服务器, 在雅虎使用的机器是专门的RHEL 容器, 双核, 2GB 内存, 和 80GB IDE 硬盘.
推荐使用单数的机器, 比如 4个机器, 如果2个机器挂了, 就没有大多数的票, 服务就不行了, 但是5个机器的话, 挂了2个, 剩下3个仍有多数票.
注意: 生产上3个机器应该够了, 但是出于维护的考虑, 用5个机器会好一点, 因为如果维护其中1个机器的话, 还可以有1个机器的容错. 如果使用3个的话, 维护1个就不能容错了. 所有的冗余考虑都需要考虑整体的环境, 比如都使用同一个网络的话, 交换机坏了整个集群也都没用了…
下面的步骤是每个机器都要执行的:
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
配置参数可以参考配置页面, 集群中的机器需要知道其他机器, 通过 server.id=host:port:port
来配置(第一个端口是成员(Quorum)端口, 第二个端口是专门用于领导选举的端口), 在 3.6.0 版本之后, 可以指定多个服务器地址, 有利于提高可用性因为服务器能够使用多个物理网络接口。指定的server id 会用来作为 myid
文件的内容. 这个 myid
文件会被放在 dataDir 指定的目录中.
6.创建一个初始化标识文件 initialize
在 myid
相同的目录中, 这个文件要使用一个空的数据目录. 当这个文件出现的时候, 一个空的数据库会被创建然后标识文件会被删除. 当没有这个文件的时候, 1个空的目录表示这个节点将没有投票权利并且 在和一个活跃的 leader 通信之前, 他都不会填充这个数据. 预期的用途就是在创建新的集群的时候应该创建这个文件.
7.如果你的配置文件创建了, 你可以通过以下命令启动ZK 服务器:
$ java -cp zookeeper.jar:lib/*:conf org.apache.zookeeper.server.quorum.QuorumPeerMain zoo.conf
QuorumPeerMain 在启动服务器的同时, 会注册 JMX 管理 beans 会同时被注册. 这样就可以通过 JMX进行管理. 详见. 可以参考 bin/zkServer.sh
中的启动命令.
$ bin/zkCli.sh -server 127.0.0.1:2181
直接配置一下 配置文件, 然后运行:
bin/zkServer.sh start
ZK的可靠性基于:
下面的小节都是基于这两个基础来考虑的
为了保证大多数机器能相互连通, 如果有F台机器可能失败, 那么应该部署 2*F+1 台服务器. 部署的机器数目最好是单数. 除此之外, 还需要考虑各种异常情况是否独立. 如果所有机器使用相同的交换机, 那么交换机坏了就都坏了, 同样道理的还有共享的电源断路器, 冷却系统等等.
如果你的ZK服务器需要连接其他的应用来获取资源比如说 CPU,存储,网络,内存等等,其性能会大大地受到它们的影响.ZK保证了持久化, 表示它需要使用存储介质来记录变化然后才允许操作成功, 所以要确保其依赖的存储介质不会挂起:
很少需要维护但是要记住以下几点:
ZK数据目录包含了一些持久化的副本. 可能是快照或者是事务日志文件, 任何变化都会被 znode 记录到 事务日志. 某些情况下, 当日志太大的时候, 会使用 快照的形式 保存到文件系统 并且 新的事务 会使用新的 日志文件.在创建快照的过程中,ZK可能还会把日志写到旧的日志文件里面, 因此 有些比 创建快照时候 更新的事务会在创建快照之前的 日志文件中被找到.
ZK服务器在默认配置下是不会移除快照和事务日志的.
PurgeTxnLog 工具实现了一个简单的持久化策略. API文档 包含了转换的细节.
下面的例子中, 最后的 count 个快照 和 关联的日志还会被保留, 其他的会被删除, 该值通常应该大于3 (尽管不是必须的, 但是它会在日志文件崩溃的时候提供至少3个备份). 这个可以被运行为 cron 任务(定时任务)来每天自动清理日志.
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
配置自动清除
使用log4j 内置的 rolling file appender
实现的, 下面会提供一个示例配置.
你可能会想要有一个自动监督每个ZK进程的监督进程. ZK服务器被设计为"快速失败", 也就是说, 如果发生了不可恢复的异常,整个ZK进程都会推出. 而ZK的"自愈性"使得服务器在重启之后可以重新加入集群.
所以可以通过监督进程比如说 daemontools 或者 SMF (其他工具都可以) 来管理ZK服务器来保证服务器异常推出的时候会系统重启(以便其重新加入集群)
同时也推荐配置ZK在发生 OOM 的时候 dump 出日志. 可以通过在启动的时候增加配置参数:
-XX:+HeapDumpOnOutOfMemoryError -XX:OnOutOfMemoryError=‘kill -9 %p’
“-XX:+HeapDumpOnOutOfMemoryError” “-XX:OnOutOfMemoryError=cmd /c taskkill /pid %%%%p /t /f”
主要通过一下方式监控:
Zk 使用 SLF4J 版本 1.7.5 作为日志基础设置. 为了兼容性它绑定了 LOG4J , 但是你可以使用 LOGBACK 或者任何其他的日志框架.
ZK默认的log4j.properties
文件在 conf
目录里面. log4j.properties
可以放在classpath 也可以放在 工作目录(ZK运行的目录)
服务器因为文件损坏而无法启动: 服务器可能会因为无法连接数据或者因为事务日志文件损坏而无法启动. 你会看到在加载ZK数据库的时候抛出的IOException. 这种情况下, 首先要保证集群中的其他服务器没有问题, 在命令行端口使用 “stat” 命令来查看它们是否正常. 如果其他服务器都正常的话, 你就可以删除 数据目录损坏的文件, 删除所有 datadir/version-2 和 datalogdir/version-2/ 中的文件, 并重启服务器.
ZK的行为是受配置文件管理的, 这个文件被设计为在每个服务器相同的目录布局中使用相同的配置. 如果配置不相同, 确保服务器列表应该一直.
注意: 在 3.5.0 或以上的版本, 有些配置参数放在了动态配置文件里面. 如果它们放在了静态配置文件中, ZK会自动将他们移动套动态配置文件.
只需要一下的配置:
注意:
小心你放置事务日志的位置, 专门的事务日志设备是确保高性能的关键. 把事务日志放在繁忙的设备上会大大的影响性能.
这些配置都是可选的, 可以用来调优. 有些配置可以通过Java的系统属性配置, 通常是使用 zookeeper.keyword 的形式:
高度推荐指定 dataLogDir 以使用单独的设备来提高性能
globalOutstandingLimit : (Java系统属性: zookeeper.globalOutstandingLimit).客户端发送过来的请求排队的最大数量. 防止太多的客户端请求撑爆服务器的内存.默认1,000
preAllocSize : (Java属性: zookeeper.preAllocSize) 事务日志预分配的空间大小. 预分配空间可以防止日志在写入的时候去磁盘查找空闲的块. 单位是 kb, 默认 64M. 修改这个配置的一个理由是, 当快照产生的很快的时候, 用来减少块的大小(见 snapCount 和 snapSizeLimitInKb)
snapCount : (Java属性: zookeeper.snapCount) ZK 使用事务日志和快照来记录事务(考虑 提前写日志 write-ahead log). snapCount 决定了多少个事务日志之后会开始产生快照. 为了防止所有的成员同时生成快照, 每个 ZK服务器会产生一个随机数处于 [snapCount/2+1, snapCount] 之间, 在达到这个随机数之后就会产生快照. 默认的 snapCount 是 100,000.
commitLogCount : (zookeeper.commitLogCount) ZK会在内存中维护一部分已提交的请求列表以供服务器间同步最近的请求的使用. 在快照很大的时候(> 100,000), 能提高同步的性能. 默认 500
snapSizeLimitInKb : (zookeeper.snapSizeLimitInKb) 和 snapCount , 但是这个使用的是文件大小来进行限制. 在拍摄快照(以及滚转事务日志)之前,事务日志中记录的事务集允许的总字节大小由snapSize确定. 为了防止多个成员同时拍摄快照, 每个成员实际使用的大小为 [snapSize/2+1, snapSize] 间的一个随机值. 默认是 4,194,304 (4GB), 负数表示不开启这个功能.
txnLogSizeLimitInKb : (zookeeper.txnLogSizeLimitInKb) 控制单个事务日志文件的大小, 默认关闭. 事务日志文件太大会影响同步性能, 因为leader需要扫描日志文件来找到合适的位置进行同步. 日志文件大小达到这个限制之后就会产生新的事务日志文件
maxCnxns : (zookeeper.maxCnxns) 限制每个zk服务器并发的连接数目(每个服务器的客户端端口). 用来放置特定类型的 DOS 工具. 默认是 0, 表示没有限制. 因为 serverCnxnFactory 和 secureServerCnxnFactory 是分开算的, 所以最多的连接数是 2 *maxCnxns
maxClientCnxns: 在 socket 层面限制一个客户端(根据ip)允许连接zk集群中某个服务器的最大连接数. 默认60. 设置成0 表示没有限制
clientPortAddress : New in 3.3.0: 监听客户端请求的地址(ipv4, ipv6, 或者hostname), 可选的, 默认监听使用 clientPort 的所有连接.
minSessionTimeout : New in 3.3.0: 默认2倍 tikeTime,毫秒
maxSessionTimeout : New in 3.3.0: 默认20倍 tikeTime ,毫秒
fsync.warningthresholdms (Java system property: zookeeper.fsync.warningthresholdms) New in 3.3.4: 日志执行 fsync 的时候超过了这个毫秒数就会打印警告信息, 默认 1000
maxResponseCacheSize : (Java system property: zookeeper.maxResponseCacheSize) 缓存序列化信息的最近读取记录的数目, 默认是 400, 负数或者 0 表示不启用, 可以使用 response_packet_cache_hits 和 response_packet_cache_misses 指标来调整这个值
maxGetChildrenResponseCacheSize (Java system property: zookeeper.maxGetChildrenResponseCacheSize) New in 3.6.0: 和 maxResponseCacheSize 类型, 但是是作用于 获取子节点的请求
autopurge.snapRetainCount: (No Java system property) New in 3.4.0: 默认3, 最小值, 保存最近的 快照 和 其关联的事务日志的数目.
autopurge.purgeInterval : (No Java system property) New in 3.4.0: 触发自动清除日志的间隔, 单位小时,默认是0
syncEnabled : (Java system property: zookeeper.observer.syncEnabled) New in 3.4.6, 3.5.0: 让观察者和其他参与者一样把事务日志写到磁盘, 减少观察者重启恢复的时间. 默认是true , 设置为 false 关闭.
fastleader.minNotificationInterval : (Java system property: zookeeper.fastleader.minNotificationInterval) 连续两次通知检查领导人选举时间的下限。领导者选举的两次连续通知检查之间的时间长度下限。 此间隔确定对等方等待检查选举投票集的时间,并影响选举可以解决的速度。 对于长选举,该间隔遵循从配置的最小值(this)和配置的最大值(fastleader.maxNotificationInterval)开始的退避策略。
fastleader.maxNotificationInterval : (Java system property: zookeeper.fastleader.maxNotificationInterval) 和上面的类似, 上限
connectionTokenFillTime : (Java system property: zookeeper.connection_throttle_fill_time) New in 3.6.0:这是用于调优服务器端连接调节器的参数之一,该调节器是一种基于令牌的速率限制机制,具有可选的概率的服务降级。 用来限流的token统计周期.
connectionTokenFillCount : (Java system property: zookeeper.connection_throttle_fill_count) New in 3.6.0: 每个统计周期 每个 token 添加到 bucket 的计数
connectionFreezeTime : (Java system property: zookeeper.connection_throttle_freeze_time) New in 3.6.0: 定义每过多长的毫秒数就调整降级概率. -1 表示不开启, 默认 -1.
connectionDropIncrease : (Java system property: zookeeper.connection_throttle_drop_increase) New in 3.6.0: connectionFreezeTime 周期内, 如果bucket为空, 就降级概率会增加 connectionDropIncrease , 默认是 0.02
connectionDropDecrease : (Java system property: zookeeper.connection_throttle_drop_decrease) New in 3.6.0:每次 connectionFreezeTime 检查周期, 如果 bucket 中的数量超过了阈值, 则服务降级的可能性减少 connectionDropDecrease . 阈值 = connectionMaxTokens * connectionDecreaseRatio, 默认是0.002
connectionDecreaseRatio : (Java system property: zookeeper.connection_throttle_decrease_ratio) New in 3.6.0: 见 connectionDropDecrease, 默认是 0
… 后面配置太多了, 有需要再去找吧
New in 3.5: 如果启动的时候还不存在数据目录(配置文件中指定的), 默认会自动创建. 这个行为有时候会非常危险, 想象这样一个例子, 如果你不小心修改了 服务器的 dataDir 的配置, 服务器就会自动在一个新的位置创建新的数据目录, 这样的话就会用一个空的命名空间进行服务器, 这种场景称为 “脑裂” (比如 同时存储了旧的数据 和 新的数据). 如果能够关闭这种创建行为就能避免这种情况了. 通常生产应该关闭自动创建, 但是因为默认的遗留行为目前还无法改变所以要具体情况具体分析.
运行 zkSever.sh 的时候 设置 环境变量 ZOO_DATADIR_AUTOCREATE_DISABLE 为 1 就可以关闭了. 如果是通过类直接运行的话, 使用 zookeeper.datadir.autocreate=false , 比如 -Dzookeeper.datadir.autocreate=false
如果关闭了自动创建, 并且发现目录不存在的话, 就会报错并且启动失败.
关闭了自动创建之后, 用户就要先安装 Zk, 然后创建一个目录文件(和潜在的 txnlog 目录), 然后再启动服务器. zkServer-initialize.sh 脚本会自动创建需要的目录, 并且可选地创建 myid 文件(通过命令行参数). 这个脚本也可以在有自动创建的时候使用. 但是注意,它只会帮你创建目录, 但是不会帮你创建配置文件.
New in 3.6.0: 默认情况下, 如果 zk 服务器启动的时候 找不到 数据树, 它会把 zxid 设置为0 并且 作为投票成员加入到集群中. 这种情况有时候会很危险, 假如数据目录是在其宕机的时候删除掉的, 那么就可能会丢失新选举的 leader中不存在的事务. 当开启了 db 存在性检查, 它在检测到没有数据树的时候, 服务器会作为非投票者加入集群之后它能够 和 leader 同步并获取到 最新的版本的集群数据. 为了表示自己确实是想要空的目录树, 可以在 myid 所在的目录创建一个 initialize 文件. 这个文件会在server启动的时候检测到然后自动帮你删除.
使用 -Dzookeeper.db.autocreate=false
来开启存在性检查, 如果使用的是 zkServer-initialize.sh , 它会自动帮你创建 initialization 文件.
… 略
… 略
… 略
New in 3.6.0: 下面的选项用来配置指标
默认情况下, zk服务器会通过 AdminServer 和 4字母命令 暴露一些有用的指标
3.6.0 以后你可以配置一个不同的指标提供者, 以提供不同系统的指标支持
3.6.0 之后 Zk 二进制包整合了 Prometheus.io
metricsProvider.className : 设置到 "org.apache.zookeeper.metrics.prometheus.PrometheusMetricsProvider"来开启 Prometheus.io 导出器.
metricsProvider.httpPort : Prometheus.io 导出器会开启一个 Jetty 服务器并绑定到这个端口, 默认是 7000. Prometheus 访问地址是 http://hostname:httPort/metrics.
metricsProvider.exportJvmInfo : 如果设置为 true Prometheus.io 会暴露关于 JVM 的有用指标.默认为 true.
3.5 版本之后 , ZK服务器能够使用 Netty 代替默认的 NIO选项. 通过设置环境变量 zookeeper.serverCnxnFactory 为 org.apache.zookeeper.server.NettyServerCnxnFactory, 对于客户端, 设置 zookeeper.clientCnxnSocket 为org.apache.zookeeper.ClientCnxnSocketNetty.
New in 3.5.5
基于 Netty 框架的通信可以设置使用TLS加密通信
注意 Quorum TLS 封装了 leader选举 和 成员通信协议 的加密
每个ZK实例都应该创建1个keystore
在这个例子中我们生了一个自签名的证书并且将其私钥一起保存在了keystore.jks
里面. 这种适合测试,但是生产上你可以要使用正式的证书.
注意 alias (-alias) 和 distinguished name (-dname) 必须匹配机器使用的hostname,否则hostname验证会无法工作.
keytool -genkeypair -alias ( h o s t n a m e − f ) − k e y a l g R S A − k e y s i z e 2048 − d n a m e " c n = (hostname -f) -keyalg RSA -keysize 2048 -dname "cn= (hostname−f)−keyalgRSA−keysize2048−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
整个集群中的成员都要使用相同的 truststore
, 其中包含了所有集群成员的证书. 这些证书在truststore
中的别名是不同的. 但是命名成什么无所谓.
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
New in 3.5.5
以下利用 端口一致化(port unification)
功能来实现在线 TLS 切换:
为集群中所有的服务器创建必要的 keystore 和 truststore (按照上节所说)
添加以下配置并且重启第一个节点
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
启动完之后要检查一下运行状态是否正常
每个节点上开启端口一致
并且依次重启
sslQuorum=true
portUnification=true
一旦完成之后并确认集群运行状态正常, 就可以关闭端口一致
并再次依次重启
sslQuorum=true
portUnification=false
所有命令都是4个字母组成的, 可以通过 telnet 或者 nc 或者zk客户端端口 触发命令
3个最常用的命令: stat
显示服务器的通用信息和 已连接的客户端. srvr
和 cons
显示关于服务器和连接更详细的信息.
New in 3.5.3: 四字命令需要在使用前配置好允许哪些命令的使用. 使用 4lw.commands.whitelist
这个配置. 后面四字命令会过期, 建议使用 AdminServer
既然以后要过期… 那就略过了.
重点说一下: trace mask
stmk : 设置当前的 trace mask. track mask 是 64位的, 每一位表示开启或者关闭特定目录的服务器上的 trace 日志. Log4J 必须设置为 trace 级别 才能看到 trace 日志信息. 以下是每个位的目录含义:
Trace Mask Bit Values | |
---|---|
0b0000000000 | 未使用,保留给未来使用 |
0b0000000010 | 打印客户端请求, 排除ping请求 |
0b0000000100 | 未使用,保留给未来使用 |
0b0000001000 | 打印ping请求 |
0b0000010000 | 打印当前leader发过来的请求包, 排除ping请求 |
0b0000100000 | 打印客户端会话的添加, 移除和校验日志 |
0b0001000000 | 打印传递到客户端的会话的监控事件. |
0b0010000000 | 打印当前leader发过来的ping请求 |
0b0100000000 | 未使用,保留给未来使用 |
0b1000000000 | 未使用,保留给未来使用 |
所有剩下的位都是未使用的,保留给未来使用. 多个 mask 使用 位或 合并运算. 默认mask 是 0b0100110010. 因此 默认trace 日志包含了 客户端请求, leader 的包和 会话的信息. 要设置mask的话, 使用 stmk 命令之后, 紧跟着 对应的mask, 以下是 perl 的例子:
$ perl -e “print ‘stmk’, pack(‘q>’, 0b0011111010)” | nc localhost 2181 250
New in 3.5.0: AdminServer 是一个嵌入式的 jetty 服务器, 为4字命令提供了http接口. 默认情况下, 使用的是 8080端口, 并且名通过 URL 的 “/commnads/[command name]” 触发. 比如 http://localhost:8080/commands/stat, 命令的响应是 json 值. 不同的是, 命令没有被限制为 4个字母, 名可以用多个名称, 比如: stmk
可以用来指代 set_trace_mask
. 通过 http://localhost:8080/commands 可以看到所有可用的命令. 见 AdminServer 配置选项 查看如何变更端口和 urls
AdminServer 默认开启, 但是可以被关闭:
注意 TCP 的四字命令在 AdminServer关闭的时候依然有用.
可用的命令如下:
ZK保存数据于数据目录, 保存事务日志在事务日志目录. 默认两个是一样的, 可以为事务日志单独配置一个目录. 使用专门的设备来保存事务日志能提高性能.
可能会包含以下2或者3个文件:
每个ZK服务器都有一个单独的id, 这个id用于两个地方: myid文件 和 配置文件. myid文件标志了给定了数据目录的服务器. 配置文件列举了其他服务器的连接地址并通过 服务器id标志. 当一个zk 服务器实例启动, 它会从myid文件读取它的id, 使用那个 id, 来从配置文件中查看自己应该监听那个端口.
保存在 数据目录的 快照
文件是 模糊快照, 表示zk服务器正在拍摄快照, 数据树正在发生变化. 快照
的最后是 zxid
, zk事务id, 即在拍摄快照开始时最后提交的事务的ZooKeeper事务id。因此,快照包括在快照进行时发生的数据树更新的子集。快照可能不会关联任何实际存在的数据树, 由此我们称之为模糊快照
. 不过,ZooKeeper仍然可以使用这个快照进行恢复,因为它利用了更新的幂等特性。通过对模糊快照重放事务日志,ZooKeeper在日志末尾获得系统的状态。
日志目录包含了ZK的事务日志. 在更新执行之前, ZK保证表示该事务的更新操作会写入到固定存储器.当事务的数量达到阈值的时候, 会创建一个新的事务日志文件. 该阈值使用 snapCount 和 snapSizeLimitInKb 参数计算出来的. 日志文件的后缀是写入到日志中的第一个事务的zxid.
不同配置 和 独立zk 和 集群zk服务器的 快照 和 事务日志文件格式并无不同. 可以直接复制到开发环境的独立的zk服务器来排查问题.
使用旧的日志和快照文件, 可以查看ZK服务器的上个状态甚至恢复成那个状态. LogFormatter 类允许管理员查看日志中的事务.
ZK服务器创建快照和日志文件, 但是不会删除它们. 文件保留策略由ZK外部实现. 服务器本身只需要最新的完整的模糊快照, 所有的跟随它的日志文件, 还有它之前的最后的日志文件. 后者是因为拍摄快照的时候, 也会同时进行更新, 所以该日志文件也是必须的. 这是可能的因为 拍摄快照 和 日志滚动 某种程度上是独立于Zk的. 查看 维护 一节来设置文件保留策略.
注意: 这些文件中的数据都是没有加密的. 可采取措施防止未授权的访问, 比如说访问控制. 这些措施也是zk外部进行的, 独立于zk本身的配置文件.
查看 ZK工具集合
略… 原文没啥营养
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。