ZooKeeper 原理与服务器集群部署
ZooKeeper 是大型分布式系统中可靠的协调系统,它以树状结构存储数据,以领导选举和信息同步机制保证了集群的高可用性,以事件通知机制协助事件订阅者及时捕获数据的变化,可协助实现 Dubbo、Kafka 等架构。本文以 CentOS 和 Windows 为例,总结了 ZooKeeper 集群的部署操作,并以自带的脚本命令操作其数据。
作者:王克锋
出处:https://kefeng.wang/2017/11/08/zookeeper-deploy/
版权:自由转载-非商用-非衍生-保持署名,转载请标明作者和出处。
1.概述
ZooKeeper 是 Hadoop 的一个子项目,是大型分布式系统中可靠的协调系统。分布式应用程序以此实现更高级别的服务,可用于分布式系统的配置维护、名字服务、分布式同步、组服务等:
- 用于 Dubbo: 作为配置中心;
- 用于 Kafka: 作为 Broker/Producer/Consumer 共享的配置中心。
官网首页: https://zookeeper.apache.org/
官网文档: https://zookeeper.apache.org/doc/current/
1.1 ZAB协议
集群间通过 ZAB(ZooKeeper Atomic Broadcast)协议保持数据一致性,该协议包括两个阶段:
1.1.1 领导选举(Leader Election)
- 选举出一个 Leader(所有写操作传送给 Leader),其他机器被称为 Follower;
- 当前 Leader 崩溃或失去大多数 Follower 后,会选举出新的 Leader;
1.1.2 信息同步(Atomic broadcast)
用于同步 Leader 与 Follower 之间的信息,保证数据一致。
1.2 内部原理
https://zookeeper.apache.org/doc/current/zookeeperOver.html
存储方式与标准文件系统非常相似,每个节点称作 znode,本身包含数据,还可以拥有子节点。
客户端以TCP连接一台节点,该节点故障时,客户端会切换至其他节点。
客户端可以订阅某些节点的事件(watcher机制),当节点内容或其子节点有变化时,客户端会收到通知。
- 高性能:多读少写的情况下,速度很快;存储于内存中,并有持久存储中的事务日志和快照;
- 高可用性(无中心化结构可避免单点故障): 个别节点故障不影响整体使用;
- 监视机制: 客户端可以监视一个结点(node),当结点断开或有修改时,客户端会收到通知;
- 顺序一致性: 来自客户端的更新将按照它们发送的顺序进行应用。
- 原子性: 保证数据完整、一致,更新成功或失败,没有部分结果。
- 单系统映像: 无论服务器连接到哪个服务器,客户端都会看到相同的服务视图。
- 可靠性: 一旦更新被应用,它将一直持续到客户覆盖更新。
- 及时性: 系统的客户观点在一定的时间范围内保证是最新的。
1.3 系统要求
ZooKeeper 以 Java 版本运行,Java 版本要求为 1.6+;
支持的操作系统包括: GNU/Linux, Solaris, FreeBSD, Windows。
2.Linux 下安装
https://zookeeper.apache.org/doc/current/zookeeperStarted.html
2.1 下载并解压(35M)
1 | # https://archive.apache.org/dist/zookeeper/ |
2.2 设置环境变量
1 | ## sudo vim /etc/profile ## 所有用户有效 |
文件保存后,Linux用户重新登录后生效。
2.3 准备目录与配置文件
1 | sudo vim $ZOOKEEPER_HOME/bin/zkInit.sh |
其中的 clientPort=218$INDEX
是提供给客户端连接的端口(2181,2182,2183);
其中的 server.N = hostname : port1 : port2
:
N
(1,2,3): “必须”是一个数字(表示这是第几号server),否则报错java.lang.NumberFormatException: For input string: "xxx"
hostname
(localhost): 是该 server 所在的域名或IP地址,为了通用,可替换为域名zk{n}.company.com 并在 hosts 里配置;port1
(2281,2282,2283): 当前 server 是 leader 时,监听此端口接受 followers 的连接,注意followers不会监听此端口(直到它升级为 leader)port2
(2291,2292,2293): 是选举 leader 时所使用的端口。
必须生成文件 $ZOOKEEPER_HOME/data/%n/myid
,其内容为 zoo.cnf 中的 N(服务器ID), 否则抛出异常 java.lang.IllegalArgumentException: $ZOOKEEPER_HOME/data/{n}/myid file is missing
2.4 服务的配置并启动
1 | ## sudo vim /usr/lib/systemd/system/zookeeper@.service |
配置为自动启动,并立即启动:1
2
3
4
5sudo systemctl daemon-reload
sudo systemctl enable zookeeper@{1,2,3}
sudo systemctl start zookeeper@{1,2,3}
sudo netstat -natp | grep LISTEN | grep -E "218|228|229"
# sudo systemctl stop zookeeper@{1,2,3}
2.5 防火墙放行
如果非本机应用需要连接 ZooKeeper,必须把所有 clientPort 端口放行。1
2
3
4
5## sudo vim /etc/sysconfig/iptables
-A INPUT -m state --state NEW -m tcp -p tcp --dport 2181 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 2182 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 2183 -j ACCEPT
## 重启生效: sudo systemctl restart iptables
2.6 客户端验证
1 | zkCli.sh -server localhost:2181 ## 进入命令行状态 |
也可集连接和命令于一行:zkCli.sh -server localhost:2181 ls /
2.7 清空数据【慎用】
1 | sudo systemctl stop zookeeper@{1,2,3} |
2.8 卸载服务【慎用】
1 | sudo systemctl stop zookeeper@{1,2,3} |
3.Windows 下安装(可用于开发)
3.1 下载
https://archive.apache.org/dist/zookeeper/
https://archive.apache.org/dist/zookeeper/zookeeper-3.4.11/
https://archive.apache.org/dist/zookeeper/zookeeper-3.4.11/zookeeper-3.4.11.tar.gz
3.2 安装
3.2.1 解压
3.2.2 修改系统环境变量
1 | set ZOOKEEPER_HOME={???}\zookeeper-3.4.11 |
3.2.3 修改 conf\zoo-%n.cfg
1 | cd/d %ZOOKEEPER_HOME% |
修改文件 conf\zoo-%n.cfg 如下(分别替换其中的 %n 为 1,2,3):1
2
3
4
5
6
7
8
9tickTime=2000
initLimit=10
syncLimit=5
clientPort=218%n
dataDir=D:/Software/Architecture/zookeeper-3.4.11/data/%n
dataLogDir=D:/Software/Architecture/zookeeper-3.4.11/logs/%n
server.1=localhost:2281:2291
server.2=localhost:2282:2292
server.3=localhost:2283:2293
参数说明与 Linux 中相关内容一样。
3.2.4 修改脚本
删除 bin\zkEnv.cmd
中的 set ZOOCFG=%ZOOCFGDIR%\zoo.cfg
一行;1
for %n in (1,2,3) do @copy/b bin\zkServer.cmd bin\zkServer%n.cmd
修改各个文件 zkServer%n.cmd
在 call "%~dp0zkEnv.cmd"
之前加一行:set ZOOCFG=%~dp0%..\conf\zoo-%n.cfg
,注意替换 %n 分别为 1/2/3
3.3 启动服务
1 | zkServer1.cmd |
3.4 客户端验证
1 | zkCli.cmd -server centos:2181 ## 连接 Linux 上服务 |
4.集群部署(生产环境)
管理员指南: https://zookeeper.apache.org/doc/current/zookeeperAdmin.html
- 要求至少为三台 ZooKeeper 服务器,最好是奇数个服务器(以便多数正常机器处理少数机器的故障),通常三台足够了,如果想更可靠,可增加至五台;
- 为避免各服务器同时发生故障,最好部署在不同机器、不同网络交换机(电路、冷却系统等)、甚至不同机房;
- 为避免内存交换,要设置足够大的 JVM 堆,比如 4G 机器可指定 3G;