ZooKeeper入门

ZooKeeper是一个开源的分布式协调服务,它允许分布式进程通过共享层级相互协调。分布式应用可以基于ZooKeeper实现数据发布订阅、负载、命名服务、Master选举、分布式锁等功能。

ZooKeeper 数据模型

ZooKeeper的视图结构和Linux文件系统类似,ZooKeeper引入了数据节点(ZNode)的概念,每一个数据节点都被称为一个ZNode,ZNode在ZooKeeper中是数据的最小单元。
每个节点都以路径表示,我们可以向节点写入数据,也可以在节点下面创建子节点。

与典型的文件系统不同的是ZooKeeper的数据保存在内存中,这样可以实现更高吞吐和低延时。

ZooKeeper ZNode

在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台机器组成
ZooKeeper Server

在生产环境中我们使用的都是真集群,而针对于学习、调研我们一般使用伪集群。
集群部署时需要修改{ZK_HOME}/conf/zoo.cfg配置文件,增加集群节点配置。

1
2
3
server.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和port

1
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个英文字母组成的命令,称为四字命令
使用四字命令有两种使用方法

  1. 使用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.
  2. 使用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
3
server.1=localhost:2881:3881
server.2=localhost:2882:3882
server.3=localhost:2883:3883

现想扩容两台ZooKeeper节点id:4和id:5加入到集群

  1. 首先向id:4和id:5节点zoo.conf配置文件中增加id:4和id:5节点配置

    1
    2
    3
    4
    5
    server.1=localhost:2881:3881
    server.2=localhost:2882:3882
    server.3=localhost:2883:3883
    server.4=localhost:2884:3884
    server.5=localhost:2885:3885
  2. 保存后重启id:4节点,进入id:4节点检查该节点与集群数据同步情况。

  3. 可以在集群任意节点上create一个测试节点用来检查id:4与集群同步情况。
  4. 反向在id:4节点上创建或修改测试节点,到集群任意点上检查同步情况。
  5. 如果正向、反向验证通过后,可以重启id:5节点,以相同检查方式做验证。
  6. 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启动时机中有做解释。