ZooKeeper是一个开源的分布式协调服务,它允许分布式进程通过共享层级相互协调。分布式应用可以基于ZooKeeper实现数据发布订阅、负载、命名服务、Master选举、分布式锁等功能。
ZooKeeper 数据模型
ZooKeeper的视图结构和Linux文件系统类似,ZooKeeper引入了数据节点(ZNode)的概念,每一个数据节点都被称为一个ZNode,ZNode在ZooKeeper中是数据的最小单元。
每个节点都以路径表示,我们可以向节点写入数据,也可以在节点下面创建子节点。
与典型的文件系统不同的是ZooKeeper的数据保存在内存中,这样可以实现更高吞吐和低延时。
在ZooKeeper中每个节点都有自己的生命周期,其长短取决于节点类型。
节点类型 | 特性 |
---|---|
持久节点 | 数据被创建后一直保存在ZooKeeper服务器中,直到删除操作对该节点删除。 |
临时节点 | 临时节点被客户端创建后,创建该节点的客户端会话失效后节点会被自动清除。临时节点中不能再创建子节点,所以临时节点就是叶子节点。 |
顺序节点 | 父节会为第一级子节点维护一个顺序,在创建子节点时为节点名添加一个数字后缀。 |
每个数据节点除了记录数据外,还会记录节点本身的状态信息。
节点状态属性 | 作用 |
---|---|
cZxid | 节点创建时的事物ID |
ctime | 节点创建时间 |
mZxid | 节点最后一次修改事物ID |
mtime | 节点最后修改时间 |
pZxid | 子节点列表最后一次修改的事物ID。 |
cversion | 子节点版本号 |
dataVersion | 数据节点版本号 |
aclVersion | 节点ACL版本号 |
ephemeralOwner | 如果节点是临时节点,则为会话的sessionID,如果是持久节点该值为0 |
dataLength | 数据内容长度 |
numChildren | 子节点数量 |
ZooKeeper 运行模式与配置
ZooKeeper有两种运行模式,集群模式与单机模式。
单机模式
单机模式只要启动一个ZooKeeper节点就可以正常提供服务,所以单机模式常在开发和测试环境中使用。
集群模式
ZooKeeper集群通常由3到5台机器组成
在生产环境中我们使用的都是真集群,而针对于学习、调研我们一般使用伪集群。
集群部署时需要修改{ZK_HOME}/conf/zoo.cfg配置文件,增加集群节点配置。1
2
3server.1=localhost:2881:3881
server.2=localhost:2882:3882
server.3=localhost:2883:3883
在每个ZooKeeper服务节点{dataDir}目录中创建myid文件,并写入对应节点id。
ZooKeeper没有使用传统的Master/Slave概念,而是为集群中的服务节点引入Leader、Follower、Observer类角色。
集群中的机器通过选举过程投票选出一个服务作为Leader,Leader可为客户端提供读、写服务。
Follower和Observer能够提供读服务。
角色 | 读/写服务 | Leader选举 |
---|---|---|
Leader | 为客户端提供读、写服务 | 不参与 |
Follower | 为客户端提供读服务 | 参与 |
Observer | 为客户端提供读服务 | 参与 |
zoo.cfg配置
参数名 | 作用 |
---|---|
clientPort | 客户端连接端口号,集群中的clientPort可以不保持一致 |
dataDir | 用于存储快照文件的目录 |
tickTime | 毫秒表示的ZooKeeper中最小时间单元长度 |
syncLimit | 一个正整数,表示tickTime的倍数。用来配置Leader与Follower心跳的最大延时 |
maxClientCnxns | 单个客户端与服务器之间连接数限制 |
server.id=localhost:port1:port2 | 用来配置ZooKeeper集群机器列表,id表示服务ID,与myid内容一致。port1表示Leader与Follower通讯端口,port2用于Leader选举通讯端口 |
命令
ZooKeeper接收客户端命令行命令,首先要使用zkCli启动客户端。连接指定的ZooKeeper服务器,使用-server指定,并指定服务端的ip和port1
zkCli.sh [-server] [ip:port]
创建一个节点,使用create命令,在下面的命令中-s指创建顺序节点,-e指创建临时节点。不添加参数认为创建持久节点。1
create [-s] [-e] path data acl
查看ZooKeeper指定节点下子节点。1
ls path [watch]
获取ZooKeeper指定节点数据内容及属性内容1
get path [watch]
为节点写入内容
ZooKeeper中节点的数据有版本的概念,version参数用于指定本次更新操作基于节点的哪一个dataVersion。
在并发修改ZooKeeper时可以利用dataVersion来加乐观锁,避免多线程修改造成数据混乱。1
set path data [version]
删除指定节点
version参数用于指定本次删除是基于哪个dataVersion。ZooKeeper中删除某节点的前提是该节点必须没有子节点存在。1
delete path [version]
查看ZooKeeper服务运行模式1
./zkServer.sh status
四字命令
ZooKeeper有很多由4个英文字母组成的命令,称为四字命令
使用四字命令有两种使用方法
使用telnet方式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22> telnet localhost 2181
Trying ::1...
Connected to localhost.
Escape character is '^]'.
>conf
clientPort=2181
dataDir=/Users/shitianshu/work/server/zookeeper/cluster/zookeeper-01/bin/../data/zookeeper/version-2
dataLogDir=/Users/shitianshu/work/server/zookeeper/cluster/zookeeper-01/bin/../data/zookeeper/version-2
tickTime=2000
maxClientCnxns=60
minSessionTimeout=4000
maxSessionTimeout=40000
serverId=1
initLimit=10
syncLimit=5
electionAlg=3
electionPort=3881
quorumPort=2881
peerType=0
Connection closed by foreign host.使用nc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16> echo conf | nc localhost 2181
clientPort=2181
dataDir=/Users/shitianshu/work/server/zookeeper/cluster/zookeeper-01/bin/../data/zookeeper/version-2
dataLogDir=/Users/shitianshu/work/server/zookeeper/cluster/zookeeper-01/bin/../data/zookeeper/version-2
tickTime=2000
maxClientCnxns=60
minSessionTimeout=4000
maxSessionTimeout=40000
serverId=1
initLimit=10
syncLimit=5
electionAlg=3
electionPort=3881
quorumPort=2881
peerType=0
四字命令 | 作用 |
---|---|
conf | 输出ZooKeeper服务器运行时使用的基本配置 |
cons | 输出当前服务器上所有客户端连接详细信息 |
ruok | Are you ok? 一个监测服务器是否运行的命令 |
stat | 输出ZooKeeper服务器的运行时状态信息 |
mntr | 比stat更为详细的服务器统计信息 |
ZooKeeper扩容和缩容
扩容
假设生产有3个ZooKeeper节点组成集群环境,分别是id:1、id:2、id:3,其中id:2是LEADER。zoo.cfg
配置文件如下1
2
3server.1=localhost:2881:3881
server.2=localhost:2882:3882
server.3=localhost:2883:3883
现想扩容两台ZooKeeper节点id:4和id:5加入到集群
首先向id:4和id:5节点
zoo.conf
配置文件中增加id:4和id:5节点配置1
2
3
4
5server.1=localhost:2881:3881
server.2=localhost:2882:3882
server.3=localhost:2883:3883
server.4=localhost:2884:3884
server.5=localhost:2885:3885保存后重启id:4节点,进入id:4节点检查该节点与集群数据同步情况。
- 可以在集群任意节点上create一个测试节点用来检查id:4与集群同步情况。
- 反向在id:4节点上创建或修改测试节点,到集群任意点上检查同步情况。
- 如果正向、反向验证通过后,可以重启id:5节点,以相同检查方式做验证。
- id:4和id:5重启检查正常后,向id:1、id:2、id:3节点
zoo.cfg
配置文件中增加id:4和id:5节点配置,并依次重启。
期间由于Leader(id:2)不可用,所以集群会重新发起Leader选举。由于ZooKeeper选举原则,最终Leader会落到id:5节点。这里需要注意,请一定将Leader节点最后重启
原因在集群扩容Leader启动时机中有做解释。