Zookeeper 由 Apache Hadoop 的 Zookeeper 子项目发展而来,Google Chubby的一个开源实现。ZooKeeper是一个分布式应用程序协调服务,提供的功能包括:配置管理,名字服务,提供分布式同步、队列管理、集群管理等。所有这些类型的服务都以分布式应用程序的某种形式使用。每次实施它们都需要做很多工作来修复不可避免的错误和竞争条件。由于难以实现这些类型的服务,应用程序最初通常会吝啬它们,这使得它们在变化的情况下变得脆弱并且难以管理。即使正确完成,这些服务的不同实现也会在部署应用程序时导致管理复杂性。从设计模式角度来看,是一个基于观察者模式设计的分布式服务管理框架,它负责存储和管理大家都关心的数据,然后接受观察者的注册,一旦这些数据的状态发生变化,Zookeeper 就将负责通知已经在 Zookeeper 上注册的那些观察者做出相应的反应,从而实现集群中类似 Master/Slave

zookeeper官方下载地址:https://www.apache.org/dyn/closer.cgi/zookeeper/

部署环境:centos 7; zookeeper-3.4.13 ;jdk1.8

1. jdk安装与环境变量配置。
这块内容直接略过,不会的自行百度。

2. zookeeper安装与配置
我这里已提前下载好zookeeper包

2.1解压并修改zoo.cfg配置文件

[root@localhost opt]#  tar -xvf zookeeper-3.4.12.tar.gz
[root@localhost opt]#  mv zookeeper-3.4.12 zookeeper
[root@localhost opt]#  mv zookeeper /app
[root@localhost opt]#  cd /opt/zookeeper
[root@localhost opt]#  mkdir data
[root@localhost zookeeper]# mv conf/zoo_sample.cfg  conf/zoo.cfg
[root@localhost zookeeper]# vim conf/zoo.cfg
# The number of milliseconds of each tick
tickTime=2000   //Zookeeper 服务器之间或客户端与服务器之间维持心跳的时间间隔,每隔tickTime时间就会发送一个心跳,单位毫秒,最小的session过期时间为tickTime的两倍,ZK中的其他时间都是以这个为倍数的。
# The number of ticks that the initial 
# synchronization phase can take
initLimit=10    //表示允许从服务器(相对于leader来说的客户端)连接到leader并完成数据同步的时间,它是以tickTime的倍数来表示的,也就是从服务器与主服务器完成初始化连接和数据同步是能够容忍多少个心跳时间,如果超过这个时间不能完成初始化连接的建立则表示连接失败。默认是10.如果你的数据量过大而且从服务器数量也多那么这个值可以设置大一点。。总的时间长度就是 initLimit * tickTime 秒。
#LeaderServes       用于配置Leader服务器是否接受客户端的连接,是否允许Leader向客户端直接提供服务,默认是可以的。
# The number of ticks that can pass between 
# sending a request and getting an acknowledgement
syncLimit=5     //配置 Leader 与 Follower 之间发送消息,请求和应答时间长度,最长不能超过多少个 tickTime 的时间长度,总的时间长度就是 syncLimit * tickTime 秒 ,如果在这个时间内从服务器不能与主服务器通信,则表示该从服务器失败。默认为5.如果集群环境网络不佳可以调整大一点。
# the directory where the snapshot is stored.
# do not use /tmp for storage, /tmp here is just 
# example sakes.
dataDir=/opt/zookeeper/data     //Zookeeper 保存数据的数据库快照的位置,默认是/tmp/zookeeper,快照文件并不是实时的,运行一段时间才会有。
dataLogDir=/opt/zookeeper/logs  //事务日志日志路径,若没提供的话则用dataDir。zookeeper的持久化都存储在这两个目录里,对ZK的读和写都是在内存中完成,所以速度非常快,但是如果停止ZK再启动数据还是需要保证的,所以就会有这样一个路径用来保存事务日志,当ZK再次启动时加载到内存重演过程来恢复数据。dataLogDir里是放到的顺序日志(WAL),指定的目录下有version-2文件夹(下有log.1文件),这个目录确定了当前事务日志的版本号,当下次某个版本的ZK对其进行修改时,版本号发生变化。日志文件大小为64M,如果数据比较多就会有多个这样大小的文件。而dataDir里放的是内存数据结构的snapshot,便于快速恢复。为了达到性能最大化,一般建议把dataDir和dataLogDir分到不同的磁盘上,建议将事物日志保存到单独的磁盘而且是高速磁盘。因为为了一致性,ZK对于客户端的写入请求在返回之前就要把本次操作写入到事物日志中
# the port at which the clients will connect
clientPort=2181     //Zookeeper服务器监听的端口,以接受客户端的访问请求。
# the maximum number of client connections.
# increase this if you need to handle more clients
#maxClientCnxns=60        限制连接到ZK上的客户端数量,并且限制并发连接数量,它通过IP来区分不同客户端。值为0表示不做任何限制。注意这里的限制是针对单台客户端到服务器的,并不是控制所有客户端连接的。默认60.
#minSessionTimeout=120     最小会话超时时间,默认为tickTime的2倍。不建议把这个值设置的比tickTime小。客户端连接到ZK时如果在这个最小时间内没有和ZK联系则标记为超时,也就是说会断开。
#maxSessionTimeout=2400     最大会话超时时间,默认为20倍的最小会话超时时间。不建议把这个值设置的比tickTime小。客户端连接到ZK时如果在这个最大时间内没有和ZK联系则标记为超时。所以上面的参数和这个参数组成了一个时间范围,也就是客户端连接ZK时如果在这个时间范围内没有成功连接则会标记为超时。如果客户端设置的时间范围不在这个服务器设置的范围内,则会被强制应用服务器设置的范围。
#
# Be sure to read the maintenance section of the 
# administrator guide before turning on autopurge.
#
# http://zookeeper.apache.org/doc/current/zookeeperAdmin.html#sc_maintenance
#
# The number of snapshots to retain in dataDir
#autopurge.snapRetainCount=3              自动清理日志,该参数设置保留多少个快照文件和对应的事务日志文件,默认为3,如果你设置的小于3则会被自动的调整为3
# Purge task interval in hours
# Set to "0" to disable auto purge feature
#autopurge.purgeInterval=1                     自动清理日志,该参数设置自动清理频率,上面的参数配套使用。客户端在和ZK服务器交互中服务器会产生很多日志,而且ZK会将内存中的数据作为快照保存起来,而且这些数据不会自动删除,那么磁盘空间就会被占用,可以设置这2个参数来自动清理,不过如果ZK服务器比较繁忙而且赶上删除日志任务就会影响性能,所以一般不设置这个自动清理,而是在ZK访问量少的时候通过Linux的定时任务来处理。0表示不开启自动清理功能。
#globalOutstandingLimit    ZK的最大请求堆积数,客户端请求比较多,为了防止客户端资源过度消耗,服务器必须限制同时处理的请求数量。
#preAllocSize   用于配置ZK事务日志预先分配的空间,默认是64M
#snapCount     用于配置相邻两次快照之间的事物日志次数,默认是10万。也就是10万条事务之后做一次快照同时结转事务日志
#clientPortAddres     这个参数针对多网卡的ZK服务器,允许为每个IP地址指定不同的监听端口。
#fsync.warningthresholdms     用于设置ZK服务器事物日志同步操作时消耗时间的报警阈值,如果实际消耗时长超过这个时间日志就会记录。
#electionAlg    用于配置Leader选举算法,目前只有一种选举算法,所以不用配置。
#cnxTimeout    用于Leader选举时各个服务器之间进行的TCP连接创建超时时间,默认为5.
#forceSync       这个参数用于配置ZK服务器是否在事物提交时是否强制写入磁盘(LINUX的延迟写入),默认是YES。
#jute.maxbuffer    用于配置单个数据节点上最大数量,默认是1MB。通常不需要改动该参数,但是因为Zookeeper不适合存放太多数据所以有时候需要把值改小
#skipACL    是否跳过ACL检查,默认是no,也就是会对所有客户端连接进行acl检查。
server.1=172.16.148.132:2888:3888
server.2=172.16.148.133:2888:3888
server.3=172.16.148.134:2888:3888
// server.n n是一个数字,表示这个是第几号服务器;“=”号后面是对应几号服务器的IP地址,第一个端口2888是集群中从服务器(follower)连接到主服务器(leader)的端口,也就是作为leader时使用的,其他从服务器都连接到主服务器的这个端口;第二个端口3888表示的是进行leader选举时使用的端口。

2.2把zookeeper加入到环境变量

#把zookeeper加入到环境变量

echo -e "# append zk_env\nexport PATH=$PATH:/opt/zookeeper/bin" >> /etc/profile

2.3、创建ServerID标识
除了修改zoo.cfg配置文件外,zookeeper集群模式下还要配置一个myid文件,这个文件需要放在dataDir目录下。

这个文件里面有一个数据就是A的值(该A就是zoo.cfg文件中server.A:B:C:D中的A),在zoo.cfg文件中配置的dataDir路径中创建myid文件。

#在172.16.148.132服务器上面创建myid文件,并设置值为1,同时与zoo.cfg文件里面的server.1保持一致,如下

echo "1" > /opt/zookeeper/data/myid

#在172.16.148.133服务器上面创建myid文件,并设置值为2,同时与zoo.cfg文件里面的server.2保持一致,如下

echo "2" > /opt/zookeeper/data/myid

#在172.16.148.134服务器上面创建myid文件,并设置值为3,同时与zoo.cfg文件里面的server.3保持一致,如下

echo "3" > /opt/zookeeper/data/myid

到此,相关配置已完成。

3.Zookeeper集群查看
3.1、启动每个服务器上面的zookeeper节点:

分别在三台服务器上启动zookeeper

/opt/zookeeper/bin/zkServer.sh start

3.2、启动完成之后查看每个节点的状态
服务器:172.16.148.132

root@localhost ~]# /opt/zookeeper/bin/zkServer.sh status
ZooKeeper JMX enabled by default
Using config: /opt/zookeeper/bin/../conf/zoo.cfg
Mode: follower

服务器:172.16.148.133

root@localhost ~]# /opt/zookeeper/bin/zkServer.sh status
ZooKeeper JMX enabled by default
Using config: /opt/zookeeper/bin/../conf/zoo.cfg
Mode: follower

服务器:172.16.148.134

[root@localhost ~]# /opt/zookeeper/bin/zkServer.sh status
ZooKeeper JMX enabled by default
Using config: /opt/zookeeper/bin/../conf/zoo.cfg
Mode: leader

4.Zookeeper集群连接
Zookeeper集群搭建完毕之后,可以通过客户端脚本连接到zookeeper集群上面,对客户端来说,zookeeper集群是一个整体,连接到zookeeper集群实际上感觉在独享整个集群的服务。

root@localhost ~]# /opt/zookeeper/bin/zkCli.sh -server 172.16.148.132:2181
Connecting to 172.16.148.132:2181
2019-03-09 13:36:44,721 [myid:] - INFO  [main:Environment@100] - Client environment:zookeeper.version=3.4.13-2d71af4dbe22557fda74f9a9b4309b15a7487f03, built on 06/29/2018 04:05 GMT
2019-03-09 13:36:44,723 [myid:] - INFO  [main:Environment@100] - Client environment:host.name=localhost
2019-03-09 13:36:44,723 [myid:] - INFO  [main:Environment@100] - Client environment:java.version=1.8.0_201
2019-03-09 13:36:44,730 [myid:] - INFO  [main:Environment@100] - Client environment:java.vendor=Oracle Corporation
2019-03-09 13:36:44,730 [myid:] - INFO  [main:Environment@100] - Client environment:java.home=/usr/local/jdk1.8.0_201/jre
2019-03-09 13:36:44,730 [myid:] - INFO  [main:Environment@100] - Client environment:java.class.path=/opt/zookeeper/bin/../build/classes:/opt/zookeeper/bin/../build/lib/*.jar:/opt/zookeeper/bin/../lib/slf4j-log4j12-1.7.25.jar:/opt/zookeeper/bin/../lib/slf4j-api-1.7.25.jar:/opt/zookeeper/bin/../lib/netty-3.10.6.Final.jar:/opt/zookeeper/bin/../lib/log4j-1.2.17.jar:/opt/zookeeper/bin/../lib/jline-0.9.94.jar:/opt/zookeeper/bin/../lib/audience-annotations-0.5.0.jar:/opt/zookeeper/bin/../zookeeper-3.4.13.jar:/opt/zookeeper/bin/../src/java/lib/*.jar:/opt/zookeeper/bin/../conf:.:/usr/local/jdk1.8.0_201//jre/lib/rt.jar:/usr/local/jdk1.8.0_201//lib/dt.jar:/usr/local/jdk1.8.0_201//lib/tools.jar
2019-03-09 13:36:44,730 [myid:] - INFO  [main:Environment@100] - Client environment:java.library.path=/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib
2019-03-09 13:36:44,730 [myid:] - INFO  [main:Environment@100] - Client environment:java.io.tmpdir=/tmp
2019-03-09 13:36:44,730 [myid:] - INFO  [main:Environment@100] - Client environment:java.compiler=<NA>
2019-03-09 13:36:44,730 [myid:] - INFO  [main:Environment@100] - Client environment:os.name=Linux
2019-03-09 13:36:44,730 [myid:] - INFO  [main:Environment@100] - Client environment:os.arch=amd64
2019-03-09 13:36:44,730 [myid:] - INFO  [main:Environment@100] - Client environment:os.version=3.10.0-957.el7.x86_64
2019-03-09 13:36:44,730 [myid:] - INFO  [main:Environment@100] - Client environment:user.name=root
2019-03-09 13:36:44,731 [myid:] - INFO  [main:Environment@100] - Client environment:user.home=/root
2019-03-09 13:36:44,731 [myid:] - INFO  [main:Environment@100] - Client environment:user.dir=/root
2019-03-09 13:36:44,731 [myid:] - INFO  [main:ZooKeeper@442] - Initiating client connection, connectString=172.16.148.132:2181 sessionTimeout=30000 watcher=org.apache.zookeeper.ZooKeeperMain$MyWatcher@277050dc
Welcome to ZooKeeper!
JLine support is enabled
[zk: 172.16.148.132:2181(CONNECTING) 0] 2019-03-09 13:36:44,931 [myid:] - INFO  [main-SendThread(172.16.148.132:2181):ClientCnxn$SendThread@1029] - Opening socket connection to server 172.16.148.132/172.16.148.132:2181. Will not attempt to authenticate using SASL (unknown error)
2019-03-09 13:36:44,942 [myid:] - INFO  [main-SendThread(172.16.148.132:2181):ClientCnxn$SendThread@879] - Socket connection established to 172.16.148.132/172.16.148.132:2181, initiating session
2019-03-09 13:36:44,965 [myid:] - INFO  [main-SendThread(172.16.148.132:2181):ClientCnxn$SendThread@1303] - Session establishment complete on server 172.16.148.132/172.16.148.132:2181, sessionid = 0x1000036cf050001, negotiated timeout = 30000

WATCHER::

WatchedEvent state:SyncConnected type:None path:null

看到这些,那么整个zookeeper集群就已经搭建并测试完成。