一、简介
ZooKeeper是一个开源的分布式协调服务,由雅虎创建,是Google Chubby的开源实现。分布式应用程序可以基于ZooKeeper实现诸如数据发布/订阅、负载均衡、命名服务、分布式协调/通知、集群管理、Master选举、分布式锁和分布式队列等功能。
二、单机部署(Standalone mode)
基础环境
- JAVA环境(检验方法:执行java -version和javac -version命令)
1. 下载并解压zookeeper
在这里下载最新的zookeeper稳定版,或者复制链接url,在shell窗口用wget命令获取
[root@localhost software]# wget http://mirrors.hust.edu.cn/apache/zookeeper/zookeeper-3.4.12/zookeeper-3.4.12.tar.gz
[root@localhost zookeeper-3.4.12]# tar -xzvf zookeeper-3.4.12.jar
[root@localhost software]# cd zookeeper-3.4.12/
2. 创建数据目录
[root@localhost ~]# mkdir /software/zookeeper-3.4.12/data
3. 生成默认配置文件并修改
[root@localhost zookeeper-3.4.12]# cp conf/zoo_sample.cfg conf/zoo.cfg
[root@localhost zookeeper-3.4.12]# vi conf/zoo.cfg
关键配置项:
tickTime=2000
dataDir=/software/zookeeper-3.4.12/data
clientPort=2181
tickTime
ZooKeeper中用到的基本时间单位(单位为毫秒). 用做心跳的时间间隔, 另外最小session超时时间一般是其2倍
dataDir
用来存放内存数据快照的目录,以及数据库更新事物日志的默认存放目录。
clientPort
监听客户端连接的端口
4. 启动zookeeper
[root@localhost zookeeper-3.4.12]# ./bin/zkServer.sh start
ZooKeeper JMX enabled by default
Using config: /software/zookeeper-3.4.12/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED
[root@localhost zookeeper-3.4.12]# jps
11830 QuorumPeerMain
11847 Jps
[root@localhost zookeeper-3.4.12]# ps -ef | grep zookeeper
root 11830 1 1 18:43 pts/0 00:00:00 /opt/jdk1.8.0_172/bin/java -Dzookeeper.log.dir=. -Dzookeeper.root.logger=INFO,CONSOLE -cp /software/zookeeper-3.4.12/bin/../build/classes:/software/zookeeper-3.4.12/bin/../build/lib/*.jar:/software/zookeeper-3.4.12/bin/../lib/slf4j-log4j12-1.7.25.jar:/software/zookeeper-3.4.12/bin/../lib/slf4j-api-1.7.25.jar:/software/zookeeper-3.4.12/bin/../lib/netty-3.10.6.Final.jar:/software/zookeeper-3.4.12/bin/../lib/log4j-1.2.17.jar:/software/zookeeper-3.4.12/bin/../lib/jline-0.9.94.jar:/software/zookeeper-3.4.12/bin/../lib/audience-annotations-0.5.0.jar:/software/zookeeper-3.4.12/bin/../zookeeper-3.4.12.jar:/software/zookeeper-3.4.12/bin/../src/java/lib/*.jar:/software/zookeeper-3.4.12/bin/../conf:.:/opt/jdk1.8.0_172/lib/dt.jar:/opt/jdk1.8.0_172/lib/tools.jar -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.local.only=false org.apache.zookeeper.server.quorum.QuorumPeerMain /software/zookeeper-3.4.12/bin/../conf/zoo.cfg
root 11858 11327 0 18:44 pts/0 00:00:00 grep --color=auto zookeeper
[root@localhost ~]# echo stat | nc localhost 2181
Zookeeper version: 3.4.12-e5259e437540f349646870ea94dc2658c4e44b3b, built on 03/27/2018 03:55 GMT
Clients:
/0:0:0:0:0:0:0:1:60346[0](queued=0,recved=1,sent=0)
Latency min/avg/max: 0/0/16
Received: 991
Sent: 990
Connections: 1
Outstanding: 0
Zxid: 0x5
Mode: standalone
Node count: 4
5. 连接zookeeper
[root@localhost zookeeper-3.4.12]# ./bin/zkCli.sh -server 127.0.0.1:2181
Connecting to 127.0.0.1:2181
2018-07-17 18:45:16,711 [myid:] - INFO [main:Environment@100] - Client environment:zookeeper.version=3.4.12-e5259e437540f349646870ea94dc2658c4e44b3b, built on 03/27/2018 03:55 GMT
2018-07-17 18:45:16,714 [myid:] - INFO [main:Environment@100] - Client environment:host.name=localhost
2018-07-17 18:45:16,714 [myid:] - INFO [main:Environment@100] - Client environment:java.version=1.8.0_172
2018-07-17 18:45:16,716 [myid:] - INFO [main:Environment@100] - Client environment:java.vendor=Oracle Corporation
2018-07-17 18:45:16,716 [myid:] - INFO [main:Environment@100] - Client environment:java.home=/opt/jdk1.8.0_172/jre
2018-07-17 18:45:16,716 [myid:] - INFO [main:Environment@100] - Client environment:java.class.path=/software/zookeeper-3.4.12/bin/../build/classes:/software/zookeeper-3.4.12/bin/../build/lib/*.jar:/software/zookeeper-3.4.12/bin/../lib/slf4j-log4j12-1.7.25.jar:/software/zookeeper-3.4.12/bin/../lib/slf4j-api-1.7.25.jar:/software/zookeeper-3.4.12/bin/../lib/netty-3.10.6.Final.jar:/software/zookeeper-3.4.12/bin/../lib/log4j-1.2.17.jar:/software/zookeeper-3.4.12/bin/../lib/jline-0.9.94.jar:/software/zookeeper-3.4.12/bin/../lib/audience-annotations-0.5.0.jar:/software/zookeeper-3.4.12/bin/../zookeeper-3.4.12.jar:/software/zookeeper-3.4.12/bin/../src/java/lib/*.jar:/software/zookeeper-3.4.12/bin/../conf:.:/opt/jdk1.8.0_172/lib/dt.jar:/opt/jdk1.8.0_172/lib/tools.jar
2018-07-17 18:45:16,716 [myid:] - INFO [main:Environment@100] - Client environment:java.library.path=/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib
2018-07-17 18:45:16,716 [myid:] - INFO [main:Environment@100] - Client environment:java.io.tmpdir=/tmp
2018-07-17 18:45:16,716 [myid:] - INFO [main:Environment@100] - Client environment:java.compiler=<NA>
2018-07-17 18:45:16,716 [myid:] - INFO [main:Environment@100] - Client environment:os.name=Linux
2018-07-17 18:45:16,716 [myid:] - INFO [main:Environment@100] - Client environment:os.arch=amd64
2018-07-17 18:45:16,716 [myid:] - INFO [main:Environment@100] - Client environment:os.version=3.10.0-514.el7.x86_64
2018-07-17 18:45:16,716 [myid:] - INFO [main:Environment@100] - Client environment:user.name=root
2018-07-17 18:45:16,716 [myid:] - INFO [main:Environment@100] - Client environment:user.home=/root
2018-07-17 18:45:16,716 [myid:] - INFO [main:Environment@100] - Client environment:user.dir=/software/zookeeper-3.4.12
2018-07-17 18:45:16,717 [myid:] - INFO [main:ZooKeeper@441] - Initiating client connection, connectString=127.0.0.1:2181 sessionTimeout=30000 watcher=org.apache.zookeeper.ZooKeeperMain$MyWatcher@255316f2
2018-07-17 18:45:16,748 [myid:] - INFO [main-SendThread(127.0.0.1:2181):ClientCnxn$SendThread@1028] - Opening socket connection to server 127.0.0.1/127.0.0.1:2181. Will not attempt to authenticate using SASL (unknown error)
Welcome to ZooKeeper!
JLine support is enabled
2018-07-17 18:45:16,867 [myid:] - INFO [main-SendThread(127.0.0.1:2181):ClientCnxn$SendThread@878] - Socket connection established to 127.0.0.1/127.0.0.1:2181, initiating session
2018-07-17 18:45:16,921 [myid:] - INFO [main-SendThread(127.0.0.1:2181):ClientCnxn$SendThread@1302] - Session establishment complete on server 127.0.0.1/127.0.0.1:2181, sessionid = 0x100021be01a0000, negotiated timeout = 30000
WATCHER::
WatchedEvent state:SyncConnected type:None path:null
[zk: 127.0.0.1:2181(CONNECTED) 0]
6. 基本命令操作
[zk: 127.0.0.1:2181(CONNECTED) 0] help
ZooKeeper -server host:port cmd args
stat path [watch]
set path data [version]
ls path [watch]
delquota [-n|-b] path
ls2 path [watch]
setAcl path acl
setquota -n|-b val path
history
redo cmdno
printwatches on|off
delete path [version]
sync path
listquota path
rmr path
get path [watch]
create [-s] [-e] path data acl
addauth scheme auth
quit
getAcl path
close
connect host:port
[zk: 127.0.0.1:2181(CONNECTED) 1] ls /
[zookeeper]
[zk: 127.0.0.1:2181(CONNECTED) 2] create /zk_test my_data
Created /zk_test
[zk: 127.0.0.1:2181(CONNECTED) 3] get /zk_test
my_data
cZxid = 0x2
ctime = Tue Jul 17 18:49:56 CST 2018
mZxid = 0x2
mtime = Tue Jul 17 18:49:56 CST 2018
pZxid = 0x2
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 7
numChildren = 0
[zk: 127.0.0.1:2181(CONNECTED) 4] set /zk_test junk
cZxid = 0x2
ctime = Tue Jul 17 18:49:56 CST 2018
mZxid = 0x3
mtime = Tue Jul 17 18:51:00 CST 2018
pZxid = 0x2
cversion = 0
dataVersion = 1
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 4
numChildren = 0
[zk: 127.0.0.1:2181(CONNECTED) 5] delete /zk_test
[zk: 127.0.0.1:2181(CONNECTED) 6] ls /
[zookeeper]
三、集群部署(Replicated mode)
1. 软件环境
ZooKeeper是一个Java语言实现的分布式协调服务框架,因此需要运行于JDK6或更高版本。通常情况下,建议使用最少3台独立的Linux服务器构成的一个ZK集群。
2. 集群模式的配置
为了确保ZooKeeper服务的稳定与可靠性,通常是搭建成一个ZK集群来对外提供服务。关于ZooKeeper,需要明确一个很重要的特性:集群中只要有过半的机器是正常工作的,那么整个集群对外就是可用的(本文下面就用“过半存活即可用”来代替这个特性吧^-^)。正是基于这个特性,建议是将ZK集群的机器数量控制为奇数较为合适。为什么选择奇数台机器,我们可以来看一下,假如是4台机器构成的ZK集群,那么只能够允许集群中有一个机器down掉,因为如果down掉2台,那么只剩下2台机器,显然没有过半。而如果是5台机器的集群,那么就能够对2台机器down掉的情况进行容灾了。
1. 安装JDK
相关链接: http://java.sun.com/javase/downloads/index.jsp
2. 设置Java heap 大小
这能有效避免内存与磁盘空间的交换,从而大大提升ZK的性能。为了确定一个合理的堆值大小,在正式发布上线之前,建议是针对使用场景进行一些压力测试,确保正常运行后内存的使用不会触发此类交换。通常在一个物理内存为4G的机器上,最多设置-Xmx为3G。
3. 下载安装ZooKeeper
相关链接: http://zookeeper.apache.org/releases.html
4. 配置文件zoo.cfg
初次使用zookeeper,按照如下这个简单配置即可:
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
clientPort | 客户端连接server的端口,即对外服务端口,一般设置为2181。 |
dataDir | 存储快照文件snapshot的目录。默认情况下,事务日志也会存储在这里。建议同时配置参数dataLogDir, 事务日志的写性能直接影响zk性能。 |
tickTime | ZK中的一个时间单元。ZK中所有时间都是以这个时间单元为基础,进行整数倍配置的。例如,session的最小超时时间是2*tickTime。 |
dataLogDir | 事务日志输出目录。尽量给事务日志的输出配置单独的磁盘或是挂载点,这将极大的提升ZK性能。 (No Java system property) |
initLimit | Follower在启动过程中,会从Leader同步所有最新数据,然后确定自己能够对外服务的起始状态。Leader允许F在 initLimit时间内完成这个工作。通常情况下,我们不用太在意这个参数的设置。如果ZK集群的数据量确实很大了,F在启动的时候,从Leader上同步数据的时间也会相应变长,因此在这种情况下,有必要适当调大这个参数了。(No Java system property) |
syncLimit | 在运行过程中,Leader负责与ZK集群中所有机器进行通信,例如通过一些心跳检测机制,来检测机器的存活状态。如果L发出心跳包在syncLimit之后,还没有从F那里收到响应,那么就认为这个F已经不在线了。注意:不要把这个参数设置得过大,否则可能会掩盖一些问题。(No Java system property) |
server.x=[hostname]:nnnnn[:nnnnn] | 这里的x是一个数字,与myid文件中的id是一致的。右边可以配置两个端口,第一个端口用于F和L之间的数据同步和其它通信,第二个端口用于Leader选举过程中投票通信。 (No Java system property) |
说明:
- 集群中的每台机器都需要感知整个集群是由哪几台机器组成的,在配置文件中,可以按照这样的格式,每行写一个机器配置:server.id=host:port:port. 关于这个id,我们称之为Server ID,标识host机器在集群中的机器序号,在每个ZK机器上,我们需要在数据目录(数据目录就是dataDir参数指定的那个目录)下创建一个myid文件,myid中就是这个Server ID数字。
- 在ZooKeeper的设计中,集群中任意一台机器上的zoo.cfg文件的内容都是一致的。因此最好是用SVN把这个文件管理起来,保证每个机器都能共享到一份相同的配置。
5. 关于myid文件。
myid文件中只有一个数字,即一个Server ID。例如,server.1 的myid文件内容就是“1”。注意,请确保每个server的myid文件中id数字不同,并且和server.id=host:port:port中的id一致。另外,id的范围是1~255。
6. 启动zookeeper
直接使用%ZK_HOME%/bin 中的脚本启动即可。
./zkServer.sh start
7. 连接zookeeper来检验部署是否成功
直接使用%ZK_HOME%/bin中的脚本连接即可,下面这个命令执行后,就进入了zookeeper树状结构的文件系统中。
./zkCli.sh
另外,还有一种方式,能够查看ZK服务器当前状态,如下,这个能够很好的看出目前这个机器的运行情况了:
$ echo stat | nc localhost 2181
Zookeeper version: 3.4.3-1240972, built on 02/06/2012 10:48 GMT
Clients:
/127.0.0.1:40293[0](queued=0,recved=1,sent=0)Latency min/avg/max: 1/2/3
Received: 4
Sent: 3
Outstanding: 0
Zxid: 0×200000006
Mode: leader
Node count: 4