环境准备
-
3台已安装 jdk 的 centos 7.5 服务器
单机模式部署
-
上传安装包到服务器的 /opt 目录
-
解压安装包,并且移动到 /usr/local 目录
cd /opt tar -zxvf apache-zookeeper-3.7.0-bin.tar.gz mv apache-zookeeper-3.7.0-bin /usr/local/apache-zookeeper-3.7.0
-
创建用来存放事务日志和快照的目录
cd /usr/local/apache-zookeeper-3.7.0 mkdir data
-
复制 zoo_sample.cfg 为 zoo.cfg
cd conf cp zoo_sample.cfg zoo.cfg
-
修改配置文件 zoo.cfg 的 dataDir 配置
vi zoo.cfg
dataDir=/usr/local/apache-zookeeper-3.7.0/data
-
启动服务
cd ../bin ./zkServer.sh start
-
测试
./zkServer.sh status jps ./zkCli.sh
伪集群模式部署
-
只有一台机器的时候可以实现伪集群模式
-
按照 单机模式部署一直执行到第4步结束之后,继续以下步骤
-
复制三个 zookeeper 文件夹
cd /usr/local # 进入 /usr/local 目录 cp -r apache-zookeeper-3.7.0/ zookeeper1 cp -r apache-zookeeper-3.7.0/ zookeeper2 cp -r apache-zookeeper-3.7.0/ zookeeper3
-
在每个 zookeeper 文件夹的 data 目录下增加 myid 文件,表示 server id
echo 1 > zookeeper1/data/myid echo 2 > zookeeper2/data/myid echo 3 > zookeeper3/data/myid
-
修改三个配置文件为以下内容,只有 dataDir 和 clientPort 不同,配置文件参数详解见文末
vi zookeeper1/conf/zoo.cfg
tickTime=2000 initLimit=10 syncLimit=5 dataDir=/usr/local/zookeeper1/data clientPort=2181 server.1=192.168.86.101:2777:3777 server.2=192.168.86.101:2888:3888 server.3=192.168.86.101:2999:3999
vi zookeeper2/conf/zoo.cfg
tickTime=2000 initLimit=10 syncLimit=5 dataDir=/usr/local/zookeeper2/data clientPort=2182 server.1=192.168.86.101:2777:3777 server.2=192.168.86.101:2888:3888 server.3=192.168.86.101:2999:3999
vi zookeeper3/conf/zoo.cfg
tickTime=2000 initLimit=10 syncLimit=5 dataDir=/usr/local/zookeeper3/data clientPort=2183 server.1=192.168.86.101:2777:3777 server.2=192.168.86.101:2888:3888 server.3=192.168.86.101:2999:3999
-
启动服务
./zookeeper1/bin/zkServer.sh start zookeeper1/conf/zoo.cfg ./zookeeper2/bin/zkServer.sh start zookeeper2/conf/zoo.cfg ./zookeeper3/bin/zkServer.sh start zookeeper3/conf/zoo.cfg
-
测试
./zookeeper1/bin/zkServer.sh status ./zookeeper2/bin/zkServer.sh status ./zookeeper3/bin/zkServer.sh status
集群模式部署
-
集群模式至少需要 2N+1 台机器,N > 0
-
在三台机器上分别按照 单机模式部署 完成到第4步结束后进行以下操作
-
在每台机器上均修改 zoo.cfg 为以下内容
vi zoo.cfg
tickTime=2000 initLimit=10 syncLimit=5 dataDir=/usr/local/apache-zookeeper-3.7.0/data clientPort=2181 server.1=192.168.86.101:2888:3888 server.2=192.168.86.102:2888:3888 server.3=192.168.86.103:2888:3888
-
在每台机器上的 dataDir 目录下创建 myid 文件,在该文件的第一行写上一个数字,和 zoo.cfg 中当前机器编号对应上
-
机器 192.168.86.101 对应编号 1,则执行
echo 1 > /usr/local/apache-zookeeper-3.7.0/data/myid
-
机器 192.168.86.102 对应编号 2,则执行
echo 2 > /usr/local/apache-zookeeper-3.7.0/data/myid
-
机器 192.168.86.103 对应编号 3,则执行
echo 3 > /usr/local/apache-zookeeper-3.7.0/data/myid
-
-
启动三台服务器
cd /usr/local/apache-zookeeper-3.7.0/bin ./zkServer.sh start
-
测试
./zkServer.sh status
配置文件详解
参数名 | 说明 | 必须 | 默认值 |
---|---|---|---|
clientPort | 用于配置当前服务器对外的服务端口,客户端会通过该端口和 zookeeper 服务器创建连接,一般设置为 2181。 在集群中每台服务器都可以配置任意可用的端口,同时,集群中的所有服务器不需要保持 clientPort 一致。 不支持系统属性方式配置 |
是 | 无 |
dataDir | 用于配置 zookeeper 服务器存储快照文件的目录。默认情况下,如果没有配置参数 dataLogDir,那么事务日志也会存储在这个目录中。考虑到事务日志的写性能直接影响 zookeeper 整体的服务能力,因此建议同时通过参数 dataLogDir 来配置 zookeeper 事务日志的存储目录。 不支持系统属性方式配置 |
是 | 无 |
tickTime | 用于配置 zookeeper 中最小时间单元的长度,很多运行的时间间隔都是使用 tickTime 的倍数来表示的。例如,zookeeper 中会话的最小超时时间默认是 2* tickTime。 不支持系统属性方式配置 |
是 | 3000ms |
dataLogDir | 用于配置 zookeeper 服务器存储事务日志文件的目录。默认情况下,zookeeper 会将事务日志文件和快照数据存储在同一个目录中。如果条件允许,可以将事务日志的存储配置在一个单独的磁盘上。事务日志记录对于磁盘的性能要求非常高,为了保证数据的一致性,zookeeper 在返回客户端事务请求响应之前,必须将本次请求对应的事务日志写入到磁盘中。因此,事务日志的写入的性能直接决定了 zookeeper 在处理事务请求时的吞吐。针对同一块磁盘的其它并发读写操作(如 zookeeper 运行时日志输出和操作系统自身的读写等),尤其是前面的数据快照操作,会极大的影响事务日志的写性能。因此尽量给事务日志的输出配置一个单独的磁盘或者是挂载点,将极大的提升 zookeeper 的整体能力。 不支持系统属性方式配置 |
否 | dataDir的值 |
initLimit | 用于配置 leader 服务器等待 follower 启动,并完成数据同步的时间。 follower 服务器在启动过程中,会与 leader 建立连接并完成对数据的同步,从而确定自己对外提供服务的起始状态。leader 服务器允许 follower 在 initLimit 时间内完成这个工作。 一般情况下,使用默认值就可以了,但 随着 zookeeper 集群管理的数据量增大, follower 服务器在启动的时候,从 Leader 上运行同步数据的时间也会相应变长,于是无法在较短的时间内完成数据同步,那么可以适当调大这个参数。 不支持系统属性方式配置 |
否 | 10 * tickTime |
syncLimit | 用于配置 leader 服务器和 follower 之间进行心跳检测的最大延时时间。在 zookeeper 集群运行过程中,Leader 服务器会与所有的 Follower 进行心跳检测来确定服务器是否存活。如果 Leader 服务器在 syncLimit 时间内无法获取到 follower 的心跳检测响应,那么 leader 就会认为该 follower 已经脱离了和自己的同步。 一般情况下,使用默认值即可,但如果部署 zookeeper 集群的网络环境质量较低(例如网络延时较大或丢包严重),那么可以适当调大这个参数。 不支持系统属性方式配置 |
否 | 5 * tickTime |
snapCount | 用于配置相邻两次数据快照之间的事务快照次数,即 zookeeper 会在 snapCount 次事务操作之后进行一次数据快照。默认值 100000 仅支持系统属性方式配置:zookeeper.snapCount |
否 | 100000 |
preAllocSize | 用于配置 zookeeper 事务日志文件预分配的磁盘空间大小 一般情况下,使用默认值即可,但如果我们将参数 snapCount 设置为比默认值更大或更新,那么 preAllocSize 参数也要随之作出变更。例如:如果我们将 snapCount 的值设为 500,同时预计每次事务操作的数据量大小最多为 1KB,那么参数 preAlloSize 设置为 500 就足够了。 仅支持系统属性方式配置: zookeeper.preAllocSize |
否 | 65535kb |
minSessionTimeout maxSessionTimeout |
用于服务端对客服端会话的超时时间进行限制,如果客户端设置的超时时间不在这个范围内,那么会被服务端强制设置为最大或最小的超时时间。 不支持系统属性方式配置 |
否 | 2 * tickTime 20 * tickTime |
maxClientCnxns | 从 socket 层面限制单个客户端与单台服务器之间的并发连接数,即以IP地址粒度来进行连接数的限制。如果把该参数设置为0,则表示对连接数不作任何限制 注意,这里仅仅只是对单台客户端机器与单台 zookeeper 服务器之间的连接数限制,并不能控制所有客户端的连接数总和。 不支持系统属性方式配置 |
否 | 60 |
jute.maxbuffer | 用于配置单个数据节点(ZNode) 上可以存储的最大数据量大小。由于 zookeeper 上不适宜存储太多的数据,往往需要将该参数设置为更小。 需要注意的是,在变更该参数的时候,需要在 zookeeper 集群中所有机器以及所有的客户端上均设置才能生效。 仅支持系统属性方式配置: jute.maxbuffer |
否 | 1M |
clientPortAddredd | 针对那些多网卡的机器,该参数允许为每个IP地址指定不同的监听端口。 不支持系统属性方式配置 |
否 | 无 |
server.id=host:port:port | 用于配置组成 zookeeper 集群的机器列表,其中 id 即为 server id,与每台服务器的 myid 文件中的数字相对应。同时,在该参数中,会配置两个端口:第一个端口用于指定 follower 服务器与 leader 进行运行时通信和数据同步时所使用的端口、第二个端口则专门用于进行 leader 选举过程中的投票通信。 在 zookeeper 服务器启动的时候,其会根据 myid 文件中配置的 server id 来确定自己是哪台服务器,并使用对应的端口来进行启动。如果在实际使用过程中,需要在同一台机器上部署多个 zookeeper 实例来构成伪集群的话,那么这些端口都需要配置成不同,如: server.1=192.168.86.101:2777:3777 server.2=192.168.86.101:2888:3888 server.3=192.168.86.101:2999:3999 不支持系统属性方式配置 |
否 | 无 |
autopurge.snapRetainCount | 用于配置 zookeeper 在自动清理的时候需要保留的快照数据文件数量和对应的事务日志文件。需要注意的是,并不是磁盘上所有的事务日志和快照数据文件都可以被清理掉,那样的话将无法恢复数据。因此参数 autopurge.snapRetainCount 的最小值是 3,如果配置的 autopurge.snapRetainCount 比3小的,那么会自动调整到3,即至少需要保留3个快照数据文件和对应的事务日志文件。 不支持系统属性方式配置 |
否。 | 3 |
autopurge.purgeInterval | 用于配置 zookeeper 进行历史文件自动清理的频率。如果配置该值为0或负数,那么就表明不需要开启定时清理的功能。zookeeper 默认不开启这个功能。 不支持系统属性方式配置 |
否 | 0 |
fsync.warningthresholdms | 用于配置 zookeeper 进行事务日志 fsync 操作时消耗时间的报警阈值。一旦进行一个 fsync 操作消耗的时间大于参数 fsync.warningthresholdms 配置的值,那么就会在日志中打印出报警日志 仅支持系统属性方式配置: zookeeper.warningthresholdms |
否 | 1000ms |
forceSync | 用于配置 zookeeper 服务器是否在事务提交的时候,将日志写入操作强制刷入磁盘,默认情况下时“yes”,即每次事务日志写入操作都会实时刷入到磁盘。如果设置为“no”,则能一定程度上提高 zookeeper 的写性能,但同时也会存在类似于机器断电这样的安全风险 仅支持系统属性方式配置: zookeeper.forceSync |
否 | yes |
globalOutstandingLimit | 用于配置 zookeeper 服务器最大请求堆积数量。在 zookeeper 服务器运行的过程中,客户端会源源不断的将请求发送到服务端,为了防止服务端资源(包括 CPU、内存和网络等)耗尽,服务端必须限制同时处理的请求数,即最大请求堆积数量 仅支持系统属性方式配置: zookeeper.globalOutstandingLimit |
否 | 1000 |
leaderServes | 用于配置 leader 服务器能否接受客户端的连接,即是否允许 leader 向客户端提供服务,默认情况下,leader 服务器能够接受并处理客户端的所有读写请求。在 zookeeper 的架构设计中,leader 主要用来进行对事务更新请求的协调以及集群本身的运行时协调,因此,可以设置让 leader 服务器不接受客户端连接,专注于进行分布式协调 仅支持系统属性方式配置: zookeeper.leaderServes |
否 | yes |
skipAcl | 用于配置 zookeeper 是否跳过 ACL 权限检查,默认情况下是 “no”,即会对每一个客户端请求进行权限检查。如果将其设置为 “yes”,则能一定程度的提高 zookeeper 的读写性能,但同时也将向所有客户端开放 zookeeper 的数据,包括那些之前设置过 ACL 权限的数据节点,也将不再接受权限控制 仅支持系统属性方式配置: zookeeper.skipACL |
否 | no |
cnxTimeout | 用于配置在 leader 选举过程中,各服务器之间进行 TCP 连接创建的超时时间。 仅支持系统属性方式配置: zookeeper.cnxTimeout |
否 | 5000ms |
常见问题
-
集群模式下,启动第一台时,使用 ./zkServer.sh status 发现系统不正常。
答:使用 ps -ef | grep java 可以发现进程存在,但使用 ./zkServer.sh status查看状态时却没有成功,原因是集群环境下当前只启动了一台,无法进行选主,此时这台机器处于 LOOKING 状态;只要当第二台机器启动之后,则会发现一台机器为 follower ,一台为 leader。
参考资料
- 从Paxos到Zookeeper 分布式一致性原理与实践 作者: 倪超