1. 简介

ZooKeeper 是一个开放源码的分布式应用程序协调服务。所谓分布式协调服务,就是能够在集群的节点中进行可靠的消息传递,以此来协调集群的工作。它能够为分布式应用提供的基础服务有:命名服务、配置维护、组服务、分布式消息队列、分布式通知/协调、分布式锁等。

2. CAP 理论

理论 描述
C
(Consistency)
一致性。
当执行一个更新操作成功后,分布式系统中的所有节点在同一时刻的数据完
全一致(这就要求分布式系统的运行就像在单机上运行一样)。
A
(Availability)
可用性。
当集群中的一个节点失效时,新的节点顶替故障的节点,整个集群对外仍然
是可用的。
P
(Partition tolerance)
分区容忍性。
支持动态(不停机)横向扩展,当系统性能遇到瓶颈时,可通过动态增加服
务器数量来提升系统的整体性能。

一个分布式系统如果丧失了分区容忍性,就意味着放弃了系统的扩展性。分布式系统本质上是不可靠的,由于网络故障无法完全避免,一旦出现就会导致整个系统的不可用,这是绝对不能容忍的。这也是大部分分布式系统都会在保证分区容忍性的前提下在一致性和可用性之间做权衡的原因。Zookeeper 是一个CP的。

3. 安装

Zookeeper官网 下载安装包,本文使用 zookeeper-3.4.10.tar.gz 安装包。

解压缩:

1
$ tar zxvf zookeeper-3.4.10.tar.gz

删除安装包:

1
$ rm -f zookeeper-3.4.10.tar.gz

4. 单机模式配置

拷贝一份 zookeeper-3.4.10/conf/zoo_sample.cfg 配置文件并重命名为 zoo.cfg:

1
2
$ cd zookeeper-3.4.10/conf/
$ cp zoo_sample.cfg zoo.cfg

编辑 zoo.cfg 配置文件:

1
$ vi zoo.cfg

内容如下:

1
2
3
4
tickTime=2000
dataDir=/usr/local/applications/zookeeper/data
dataLogDir=/usr/local/applications/zookeeper/logs
clientPort=2181

参数说明:

参数 描述
tickTime 基本时间单位(毫秒)
dataDir 数据目录的路径
dataLogDir 日志目录的路径
clientPort 端口号

启动服务命令(在 bin 目录下执行):

1
$ ./zkServer.sh start

重启服务命令(在 bin 目录下执行):

1
$ ./zkServer.sh restart

查看服务状态(在 bin 目录下执行):

1
$ ./zkServer.sh status

停止服务命令(在 bin 目录下执行):

1
$ ./zkServer.sh stop

5. 伪集群模式配置

伪集群是指在单台机器中启动多个 Zookeeper 服务并组成一个集群。Zookeeper 集群中只要有过半的节点是正常的,那么整个集群对外就是可用的。基于这种特性,Zookeeper 集群的节点数量通常为奇数个。

拷贝三份 Zookeeper:

1
2
3
$ cp -r zookeeper-3.4.10/ zookeeper-1
$ cp -r zookeeper-3.4.10/ zookeeper-2
$ cp -r zookeeper-3.4.10/ zookeeper-3

配置 zookeeper-1/conf/zoo.cfg:

1
2
3
4
5
6
7
8
9
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/usr/local/applications/zookeeper/cluster/node1/data
dataLogDir=/usr/local/applications/zookeeper/cluster/node1/logs
clientPort=2181
server.1=127.0.0.1:8881:9991
server.2=127.0.0.1:8882:9992
server.3=127.0.0.1:8883:9993

参数说明:

参数 描述
initLimit 初始化连接时, follower 和 leader 之间的最长心跳时间。若设置为 10,表示 10 倍的 tickTime 时间
syncLimit leader 和 follower 之间发送消息,请求和应答的最大时间。若设置为 5,表示 5 倍的 tickTime 时间
server.X=A:B:C X 是一个数字,表示这是第几个服务。A 是服务器的IP地址。B 是服务器和 leader 交换消息所使用的端口。C 是选举 leader 时所使用的端口

zookeeper-2 和 zookeeper-3 的配置与 zookeeper-1 基本相同,只需改变 dataDir、dataLogDir、clientPort 参数的值。配置 zookeeper-2/conf/zoo.cfg:

1
2
3
4
5
6
7
8
9
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/usr/local/applications/zookeeper/cluster/node2/data
dataLogDir=/usr/local/applications/zookeeper/cluster/node2/logs
clientPort=2182
server.1=127.0.0.1:8881:9991
server.2=127.0.0.1:8882:9992
server.3=127.0.0.1:8883:9993

配置 zookeeper-3/conf/zoo.cfg:

1
2
3
4
5
6
7
8
9
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/usr/local/applications/zookeeper/cluster/node3/data
dataLogDir=/usr/local/applications/zookeeper/cluster/node3/logs
clientPort=2183
server.1=127.0.0.1:8881:9991
server.2=127.0.0.1:8882:9992
server.3=127.0.0.1:8883:9993

在相应的数据目录下创建 myid 文件,并输入相对应的数字编号的值作为内容:

1
2
3
4
5
6
7
8
$ mkdir -p /usr/local/applications/zookeeper/cluster/node1/data
$ vi /usr/local/applications/zookeeper/cluster/node1/data/myid # 输入内容:1
$ mkdir -p /usr/local/applications/zookeeper/cluster/node2/data
$ vi /usr/local/applications/zookeeper/cluster/node2/data/myid # 输入内容:2
$ mkdir -p /usr/local/applications/zookeeper/cluster/node3/data
$ vi /usr/local/applications/zookeeper/cluster/node3/data/myid # 输入内容:3

启动服务命令:

1
2
3
$ zookeeper-1/bin/zkServer.sh start
$ zookeeper-2/bin/zkServer.sh start
$ zookeeper-3/bin/zkServer.sh start

查看服务状态:

1
2
3
$ zookeeper-1/bin/zkServer.sh status
$ zookeeper-2/bin/zkServer.sh status
$ zookeeper-3/bin/zkServer.sh status

6. 集群模式配置

集群模式的配置和伪集群的配置基本相同。在集群模式下,由于各个服务部署在不同的主机上,因此,zoo.cfg 配置文件的配置内容可以是完全一样的。

1
2
3
4
5
6
7
8
9
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/usr/local/applications/zookeeper/data
dataLogDir=/usr/local/applications/zookeeper/logs
clientPort=2181
server.1=192.168.1.101:2555:3555
server.2=192.168.1.102:2555:3555
server.3=192.168.1.103:2555:3555

在各主机相应的数据目录下创建 myid 文件,并输入相对应的数字编号的值作为内容:

1
2
3
4
5
6
7
8
$ mkdir -p /usr/local/applications/zookeeper/data
$ vi /usr/local/applications/zookeeper/data/myid # 192.168.1.101 输入内容:1
$ mkdir -p /usr/local/applications/zookeeper/data
$ vi /usr/local/applications/zookeeper/data/myid # 192.168.1.102 输入内容:2
$ mkdir -p /usr/local/applications/zookeeper/data
$ vi /usr/local/applications/zookeeper/data/myid # 192.168.1.103 输入内容:3

各主机防火墙分别开放相对应的端口:

1
2
3
-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 2555 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 3555 -j ACCEPT

各主机启动服务命令:

1
$ zookeeper-3.4.10/bin/zkServer.sh start

查看服务状态:

1
$ zookeeper-3.4.10/bin/zkServer.sh status