在一台主机上跑多个zk实例,每个zk实例对应一个独立的配置文件;但是每个配置文件的clientPort & admin.serverPort & dataDir & dataLogDir绝对不能相同,还需要在dataDir中创建myid文件来指定该dataDir对应的zk实例。

安装Java

#安装好JDK,可参考之前单机安装
[root@zookeeper ~]# java -version 
java version "1.8.0_351"
Java(TM) SE Runtime Environment (build 1.8.0_351-b10)
Java HotSpot(TM) 64-Bit Server VM (build 25.351-b10, mixed mode)
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.

安装JAVA, 请见

 http://qiangsh.blog.51cto.com/3510397/1771748

准备ZooKeeper

下载,解压软件
wget https://dlcdn.apache.org/zookeeper/zookeeper-3.9.2/apache-zookeeper-3.9.2-bin.tar.gz
tar zxvf apache-zookeeper-3.9.2.tar.gz -C /usr/local/
ln -s /usr/local/apache-zookeeper-3.9.2 /usr/local/zookeeper
  • 1.
  • 2.
  • 3.
配置zookeeper的环境变量
[root@zookeeper ~]# vim /etc/profile
#文件末尾增加以下两行
export ZOOKEEPER_HOME=/usr/local/zookeeper
export PATH=$PATH:$ZOOKEEPER_HOME/bin
                   
[root@zookeeper ~]# source /etc/profile
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
创建Zookeeper项目目录
#创建项目目录
mkdir -p /data/zookeeper

#创建数据目录
mkdir -p /data/zookeeper/{zkdata_0,zkdata_1,zkdata_2}

#创建事务日志目录,官方建立尽量给事务日志作单独的磁盘或挂载点,这会极大的提高zk性能
mkdir -p /data/zookeeper/{zkdatalog_0,zkdatalog_1,zkdatalog_2}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.

配置ZooKeeper

创建myid文件,并填入ID值
echo 0 > /data/zookeeper/zkdata_0/myid
echo 1 > /data/zookeeper/zkdata_1/myid
echo 2 > /data/zookeeper/zkdata_2/myid
  • 1.
  • 2.
  • 3.
准备配置文件
cd /usr/local/zookeeper/conf/
cp zoo_sample.cfg zoo_0.cfg
cp zoo_sample.cfg zoo_1.cfg
cp zoo_sample.cfg zoo_2.cfg
  • 1.
  • 2.
  • 3.
  • 4.
修改配置文件
配置server0
[root@zookeeper conf]# egrep -v "^$|^#" zoo_0.cfg
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/data/zookeeper/zkdata_0/
dataLogDir=/data/zookeeper/zkdatalog_0/
clientPort=12180
admin.serverPort=18080 # admin.serverPort 默认占8080端口

##############cluster###############
server.0=localhost:12887:13887
server.1=localhost:12888:13888
server.2=localhost:12889:13889
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
配置server1
[root@zookeeper conf]# egrep -v "^$|^#" zoo_1.cfg
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/data/zookeeper/zkdata_1/
dataLogDir=/data/zookeeper/zkdatalog_1/
clientPort=12181
admin.serverPort=18081 # admin.serverPort 默认占8080端口

##############cluster###############
server.0=localhost:12887:13887
server.1=localhost:12888:13888
server.2=localhost:12889:13889
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
配置server2
[root@zookeeper conf]# egrep -v "^$|^#" zoo_2.cfg
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/data/zookeeper/zkdata_2/
dataLogDir=/data/zookeeper/zkdatalog_2/
clientPort=12182
admin.serverPort=18082 # admin.serverPort 默认占8080端口

##############cluster###############
server.0=localhost:12887:13887
server.1=localhost:12888:13888
server.2=localhost:12889:13889
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.

配置参数zoo.cfg解读

  • tickTime=2000:通信心跳时间,Zookeeper服务器与客户端心跳时间,单位毫秒。配置服务器与客户端或服务器与服务器之间的通信心跳时间。
  • initLimit = 10:LF初始通信时限。表示Leader和Follower初始连接时能容忍的时间,10代表10个tickTime,超过该时间则认为通信失败。
  • syncLimit = 5:LF同步通信时限。Leader和Follower之间通信时间如果超过syncLimit * tickTime,Leader认为Follwer挂掉,从服务器列表中删除Follwer。
  • dataDir:保存Zookeeper中的数据。注意:默认的tmp目录,容易被Linux系统定期删除,所以一般不用默认的tmp目录。
  • clientPort = 2181:客户端连接端口,通常不做修改。

server.A=B:C:D解读

👉在每个服务器中都启动zookeeper,会通过选举机制来产生follower跟leader

  • A 是一个数字,表示这个是第几号服务器; 集群模式下配置一个文件 myid,这个文件在 data 目录下,这个文件里面有一个数据 就是 A 的值,Zookeeper 启动时读取此文件,拿到里面的数据与 zoo.cfg 里面的配置信息比 较从而判断到底是哪个 server
  • B 是这个服务器的地址
  • C 是这个服务器 Follower 与集群中的 Leader 服务器交换信息的端口
  • D 是万一集群中的 Leader 服务器挂了,需要一个端口来重新进行选举,选出一个新的 Leader,而这个端口就是用来执行选举时服务器相互通信的端口

启动ZooKeeper

#启动各实例
cd /usr/local/zookeeper/conf/
zkServer.sh start zoo_0.cfg
zkServer.sh start zoo_1.cfg 
zkServer.sh start zoo_2.cfg
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.

启动失败!查看日志发现:Error: Could not find or load main class org.apache.zookeeper.server.quorum.QuorumPeerMain,下载的安装包不对,退到zookeeper文件下,执行编译:mvn package -Dmaven.test.skip=true

测试连接
#各实例都启动之后就可以使用客户端进行连接了
[root@zookeeper conf]# zkCli.sh -server localhost:12180
# 查看当前znode中所包含的内容
[zk: localhost:12180(CONNECTED) 0] ls /

# 查看当前节点详细数据
[zk: localhost:12180(CONNECTED) 1] ls -s /
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
编写启动脚本
  • zookeeper01
cat << EOF >/usr/lib/systemd/system/zookeeper01.service
[Unit]
Description=Zookeeper Cluster - Service01
After=network.target

[Service]
Type=forking
KillMode=control-group
ExecStart=/usr/local/zookeeper/bin/zkServer.sh start zoo_0.cfg
ExecStop=/usr/local/zookeeper/bin/zkServer.sh stop zoo_0.cfg
ExecReload=/bin/kill -s HUP \$MAINPID
SuccessExitStatus=0 143
PrivateTmp=true
LimitNOFILE=1000000
LimitNPROC=100000
TimeoutStopSec=10s
Restart=on-failure
RestartSec=30

[Install]
WantedBy=multi-user.target
EOF
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • zookeeper02
cat << EOF >/usr/lib/systemd/system/zookeeper02.service
[Unit]
Description=Zookeeper Cluster - Service02
After=network.target

[Service]
Type=forking
KillMode=control-group
ExecStart=/usr/local/zookeeper/bin/zkServer.sh start zoo_1.cfg
ExecStop=/usr/local/zookeeper/bin/zkServer.sh stop zoo_1.cfg
ExecReload=/bin/kill -s HUP \$MAINPID
SuccessExitStatus=0 143
PrivateTmp=true
LimitNOFILE=1000000
LimitNPROC=100000
TimeoutStopSec=10s
Restart=on-failure
RestartSec=30

[Install]
WantedBy=multi-user.target
EOF
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • zookeeper03
cat << EOF >/usr/lib/systemd/system/zookeeper03.service
[Unit]
Description=Zookeeper Cluster - Service03
After=network.target

[Service]
Type=forking
KillMode=control-group
ExecStart=/usr/local/zookeeper/bin/zkServer.sh start zoo_2.cfg
ExecStop=/usr/local/zookeeper/bin/zkServer.sh stop zoo_2.cfg
ExecReload=/bin/kill -s HUP \$MAINPID
SuccessExitStatus=0 143
PrivateTmp=true
LimitNOFILE=1000000
LimitNPROC=100000
TimeoutStopSec=10s
Restart=on-failure
RestartSec=30

[Install]
WantedBy=multi-user.target
EOF
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
重启zookeeper
systemctl restart zookeeper01.service
systemctl restart zookeeper02.service
systemctl restart zookeeper03.service
  • 1.
  • 2.
  • 3.