Zookeeper集群安装和配置

首先我们准备四个虚拟机并提前安装好java环境,虚拟机ip分别为:

192.168.85.128
192.168.85.129
192.168.85.130
192.168.85.131

官网地址:https://zookeeper.apache.org/

  1. 进入官网点击Download
  2. zookeeper的界面_zookeeper的界面

  3. 这里下载最新版本,复制链接地址
  4. zookeeper的界面_apache_02

  5. 在128服务器中,通过wget下载,解压,创建/opt/djh并将解压后的文件夹移动到该目录下
[root@localhost ~]# wget https://downloads.apache.org/zookeeper/zookeeper-3.8.0/apache-zookeeper-3.8.0-bin.tar.gz
[root@localhost ~]# tar xf apache-zookeeper-3.8.0-bin.tar.gz
[root@localhost ~]# mkdir /opt/djh
[root@localhost ~]# mv apache-zookeeper-3.8.0-bin /opt/djh/
  1. 关于zk的配置文件
[root@localhost ~]# cd /opt/djh/apache-zookeeper-3.8.0-bin/conf
[root@localhost conf]# ll
总用量 16
-rw-r--r--. 1 1000 ftp  535 2月  25 16:47 configuration.xsl
-rw-r--r--. 1 1000 ftp 4559 2月  25 16:47 logback.xml
-rw-r--r--. 1 1000 ftp 1183 2月  25 16:47 zoo_sample.cfg
[root@localhost conf]# cp zoo_sample.cfg zoo.cfg        #复制一份,名叫zoo.cfg,zk启动时会默认加载这个配置文件 
[root@localhost conf]# ll
总用量 20
-rw-r--r--. 1 1000 ftp   535 2月  25 16:47 configuration.xsl
-rw-r--r--. 1 1000 ftp  4559 2月  25 16:47 logback.xml
-rw-r--r--. 1 root root 1183 5月   3 15:21 zoo.cfg
-rw-r--r--. 1 1000 ftp  1183 2月  25 16:47 zoo_sample.cfg
  1. 配置文件参数含义
  1. tickTime =2000:通信心跳数,Zookeeper 服务器与客户端心跳时间,单位毫秒
    Zookeeper 使用的基本时间,服务器之间或客户端与服务器之间维持心跳的时间间隔,也就是每个tickTime 时间就会发送一个心跳,时间单位为毫秒。它用于心跳机制,并且设置最小的 session 超时时间为两倍心跳时间。(session 的最小超时时间是 2*tickTime)
  2. initLimit =10:LF 初始通信时限
    集群中的 Follower 跟随者服务器与 Leader 领导者服务器之间初始连接时能容忍的最多心跳数(tickTime的数量),用它来限定集群中的 Zookeeper 服务器连接到 Leader 的时限。
  3. syncLimit =5:LF 同步通信时限
    集群中 Leader 与 Follower 之间的最大响应时间单位,假如响应超过 syncLimit * tickTime,Leader 认为 Follwer 死掉,从服务器列表中删除 Follwer。
  4. dataDir:数据文件目录+数据持久化路径
    主要用于保存 Zookeeper 中的数据(最好手动修改一下路径,不要用默认路径)。
  5. clientPort =2181:客户端连接端口
    监听客户端连接的端口。
  1. 修改配置文件
# The number of milliseconds of each tick
tickTime=2000
# The number of ticks that the initial
# synchronization phase can take
initLimit=10
# The number of ticks that can pass between
# sending a request and getting an acknowledgement
syncLimit=5
# the directory where the snapshot is stored.
# do not use /tmp for storage, /tmp here is just
# example sakes.
dataDir=/var/djh/zk     							#修改一下日志路径
# the port at which the clients will connect
clientPort=2181
# the maximum number of client connections.
# increase this if you need to handle more clients
#maxClientCnxns=60
#
# Be sure to read the maintenance section of the
# administrator guide before turning on autopurge.
#
# https://zookeeper.apache.org/doc/current/zookeeperAdmin.html#sc_maintenance
#
# The number of snapshots to retain in dataDir
#autopurge.snapRetainCount=3
# Purge task interval in hours
# Set to "0" to disable auto purge feature
#autopurge.purgeInterval=1

## Metrics Providers
#
# https://prometheus.io Metrics Exporter
#metricsProvider.className=org.apache.zookeeper.metrics.prometheus.PrometheusMetricsProvider
#metricsProvider.httpHost=0.0.0.0
#metricsProvider.httpPort=7000
#metricsProvider.exportJvmInfo=true
server.1=192.168.85.128:2888:3888        #配置文件中要指定集群中有几个节点
server.2=192.168.85.129:2888:3888        #端口3888用来服务第一次启动以及leader挂掉以后Follower们选主用的端口
server.3=192.168.85.130:2888:3888        #有了leader后leader会启动端口2888用来供其他节点连接,创建节点等行为在这个 
server.4=192.168.85.131:2888:3888        #2888端口进行
    									 #如果在后面追加:observer,则该节点角色为observer

Leader:领导者,所有写操作都由它来执行。

Follower:追随者,读操作,当Leader挂掉后参与投票选举。

Observer:观察者,读操作,不参与选举。

  1. 在保存日志的目录建一个myid文件
[root@localhost conf]# mkdir -p /var/djh/zk
[root@localhost conf]# cd /var/djh/zk/
[root@localhost zk]# vi myid
#在文件内容中只需要写一个1
  1. 然后分发到其他节点(192.168.85.129、192.168.85.130、192.168.85.131)
[root@localhost zk]# cd /opt/
[root@localhost opt]# scp -r ./djh/ root@192.168.85.129:/opt
root@192.168.85.129's password:    #输入对方密码
...
[root@localhost opt]# scp -r ./djh/ root@192.168.85.130:/opt
root@192.168.85.129's password:    #输入对方密码
...
[root@localhost opt]# scp -r ./djh/ root@192.168.85.131:/opt
root@192.168.85.129's password:    #输入对方密码
  1. 此时其他几个节点都有了zk,并且配置文件都相同,但是每个节点的myid不能相同
#在192.168.85.129服务器中myid设置为2
[root@localhost /]# mkdir -p /var/djh/zk
[root@localhost /]# echo 2 > /var/djh/zk/myid 
[root@localhost /]# cat /var/djh/zk/myid 
2

#在192.168.85.130服务器中myid设置为3
[root@localhost /]# mkdir -p /var/djh/zk
[root@localhost /]# echo 3 > /var/djh/zk/myid 
[root@localhost /]# cat /var/djh/zk/myid 
3

#在192.168.85.131服务器中myid设置为4
[root@localhost /]# mkdir -p /var/djh/zk
[root@localhost /]# echo 4 > /var/djh/zk/myid 
[root@localhost /]# cat /var/djh/zk/myid 
4
  1. 配置环境变量,并将profile文件也分发到其他节点
[root@localhost opt]# vi /etc/profile
#文件的最后加上
export ZOOKEEPER_HOME=/opt/djh/apache-zookeeper-3.8.0-bin
export PATH=$PATH:${JAVA_PATH}:${ZOOKEEPER_HOME}/bin
[root@localhost opt]# source /etc/profile
[root@localhost opt]# scp /etc/profile root@192.168.85.129:/etc
[root@localhost opt]# scp /etc/profile root@192.168.85.130:/etc
[root@localhost opt]# scp /etc/profile root@192.168.85.131:/etc
  1. 在其他节点服务器上也要刷新/etc/profile文件
  2. 开始启动集群,依次启动192.168.85.128、192.168.85.129、192.168.85.130、192.168.85.131
#前台阻塞运行,方便查看日志
[root@localhost conf]# zkServer.sh start-foreground
  1. 当第三个节点启动时,已满足过半选举,且因为myid大者为主的原因,此时在日志中可以看到已将192.168.85.130选为leader,当第四个节点192.168.85.131启动时,因为已经有了leader,所以192.168.85.131也会追随已有的leader
#192.168.85.128日志
2022-05-03 21:23:49,239 [myid:] - INFO  [QuorumPeer[myid=1](plain=[0:0:0:0:0:0:0:0]:2181)(secure=disabled):o.a.z.s.q.QuorumPeer@903] - Peer state changed: following

#192.168.85.129日志
2022-05-03 21:23:49,081 [myid:] - INFO  [QuorumPeer[myid=2](plain=[0:0:0:0:0:0:0:0]:2181)(secure=disabled):o.a.z.s.q.QuorumPeer@903] - Peer state changed: following

#192.168.85.130日志
2022-05-03 21:23:49,184 [myid:] - INFO  [QuorumPeer[myid=3](plain=[0:0:0:0:0:0:0:0]:2181)(secure=disabled):o.a.z.s.q.QuorumPeer@903] - Peer state changed: leading

#192.168.85.131日志
2022-05-03 21:31:02,827 [myid:] - INFO  [QuorumPeer[myid=4](plain=[0:0:0:0:0:0:0:0]:2181)(secure=disabled):o.a.z.s.q.QuorumPeer@903] - Peer state changed: following

如果停掉192.168.85.130,会以很快的速度将192.168.85.131选为leader

  1. 此时集群已搭建完成,下面操作一下常用命令
#开启客户端随便连接一个server,这里连接第一个节点
[root@localhost ~]# zkCli.sh
#查看根目录
[zk: localhost:2181(CONNECTED) 0] ls /
[zookeeper]
#创建djh目录
[zk: localhost:2181(CONNECTED) 1] create /djh
Created /djh
[zk: localhost:2181(CONNECTED) 2] ls /
[djh, zookeeper]
#djh目录下写数据
[zk: localhost:2181(CONNECTED) 10] set /djh "hello"
#查看djh目录下的数据
[zk: localhost:2181(CONNECTED) 12] get /djh 
hello
#查看djh目录下的数据详细信息
[zk: localhost:2181(CONNECTED) 13] get -s /djh 
hello
cZxid = 0x20000000d                     #创建该节点的事务id
ctime = Tue May 03 22:32:48 CST 2022	#被创建时间
mZxid = 0x20000000e						#该节点的最后修改的事务id,与其子节点无关
mtime = Tue May 03 22:32:59 CST 2022	#修改时间
pZxid = 0x20000000d						#该节点的子节点(或该节点)最近一次创建、删除的zxid
cversion = 0							#znode子节点变化号,znode子节点修改次数
dataVersion = 1							#znode数据变化号	
aclVersion = 0							#znode访问控制列表的变化号
ephemeralOwner = 0x0					#如果是临时节点,这个是znode拥有者的session id。如果不是临时节点则是0
dataLength = 5							#znode的数据长度
numChildren = 0							#znode子节点数量	

#新增临时节点,随着session断开而消失(客户端在连接到server的时候会产生session并伴有一个session id)
[zk: localhost:2181(CONNECTED) 14] create -e /djh "world"
#创建伴有持久序列的节点:为了防止在并发下多个客户端创建相同节点。
[zk: localhost:2181(CONNECTED) 15] create -s /djh/aaa "hello"
Created /djh/aaa0000000001
#创建伴有临时序列的节点:在创建znode的client和zookeeper断开连接后,znode被自动删除,创建时名称会自动添加编号,编号会自动递增
[zk: localhost:2181(CONNECTED) 16] create -s -e /djh/aaa "hello"
Created /djh/aaa0000000002

小知识点

  1. 在Zookeeper中没有目录和文件等概念,而是有一个数据节点的概念,称之为 ZNode。而每一个 ZNode则是我们每个路径创建对应的节点,每个 ZNode上可以保存数据,并且还可以挂载子 ZNode节点。
    在每个 ZNode中有一个事务ID的概念,在Zookeeper中将每个数据的变更操作视为事务操作,其中包括数据节点的创建、删除、更新与会话的变更等。而每一次事务操作,zookeeper都会为其分配一个全局的事务ID,用ZXID表示,定义为64位的数字,而ZXID的大小也代表了zookeeper执行操作的顺序性,其中后32位代表事务递增id,前32位是leader的纪元(第几个leader)
  2. 客户端连接产生session(包括断开连接)也会消耗一个事务id,leader会将客户端连接的session id同步到所有的follower的内存中。