概述
Zookeeper 是一个分布式的、开放源码的分布式应用程序协调服务。分布式应用可以使用它来实现诸如统一命名服务、配置管理、分布式锁服务、集群管理等功能。
说白了 ZK 就是通过管理节点(用一个路径表示)的注册、离开和更改,来实现分布式管理。
Zookeeper 会话
会话就是一个客户端与服务器之间的一个 TCP 长连接。客户端和服务器的一切交互都是通过这个长连接进行的;会话在客户端与服务器断开连接后,经过设定的 sessionTimeout 时间没有重新连接即失效。
TCP 长连接多用于操作频繁,点对点的通讯,因为操作频繁,长连接可以省去连接的建立操作和断开操作,从而节省时间。例如:数据库的连接。
TCP 的短连接多用于没有太多数据交互的场合,这样通过一次连接完成数据交互,完成以后断开连接,操作比较简单。例如:WEB 网站的 http 服务一般都用短链接,WEB 网站这么频繁的成千上万甚至上亿客户端的连接用短连接会更省一些资源。
Zookeeper 节点类型
- 持久节点(PERSISTENT)
所谓持久节点,是指在节点创建后,就一直存在,直到有删除操作来主动清除这个节点。持久节点不会因为创建该节点的客户端会话失效而消失。 - 持久顺序节点(PERSISTENT_SEQUENTIAL)
这类节点的基本特性和上面的节点类型是一致的。除此之外,在 ZK 中,每个父节点会为他的第一级子节点维护一份时序,会记录每个子节点创建的先后顺序。基于这个特性,在创建子节点的时候,可以设置这个属性,那么在创建节点过程中,ZK 会自动为给定节点名加上一个数字后缀,作为新的节点名。这个数字后缀的范围是整型的最大值。 在创建节点的时候只需要传入例如 “/test_” 这样的节点名之后,ZK 自动会给 “test_” 后面补充数字。 - 临时节点(EPHEMERAL)
和持久节点不同的是,临时节点的生命周期和客户端会话绑定。也就是说,如果客户端会话失效,那么这个节点就会自动被清除掉。注意,这里提到的是会话失效,而非连接断开。另外,在临时节点下面不能创建子节点。 - 临时顺序节点(EPHEMERAL_SEQUENTIAL)
此节点是属于临时节点,不过带有顺序,客户端会话结束节点就消失。下面是一个利用该特性的分布式锁的案例流程。- 客户端调用
create()
方法创建名为 “locknode/
guid-lock-” 的临时顺序节点。 - 客户端调用
getChildren(“locknode”)
方法来获取所有已经创建的子节点,注意,这里不注册任何Watcher。 - 客户端获取到所有子节点 path 之后,如果发现自己创建的节点序号最小,就认为这个客户端获得了锁;如果自己并非所有子节点中最小的,说明自己还没有获取到锁,此时客户端需要找到比自己小的那个节点,然后对其调用
exist()
方法,同时注册事件监听。 - 之后当这个被关注的节点被移除了,客户端会收到相应的通知。这个时候客户端需要再次调用
getChildren(“locknode”)
方法来获取所有已经创建的子节点,再次开始判断自己是否获得了锁。
- 客户端调用
补充:
客户端长时间不做增删改查 znode 操作,客户端并没有收到会话超时,原因是客户端会定时的向 Zookeeper 服务器端发送心跳包,以保持会话有效。
安装使用
官网下载客户端后,在 src/c 目录下安装:
$ ./configure
$ make
$ sudo make install
进入 conf 目录,将 zoo_sample.cfg 改名为 zoo.cfg,因为 Zookeeper 在启动时会找这个文件作为默认配置文件。参数值设置示例:
# 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.
dataDir=/home/admin/liangxiao/zookeeper-3.4.13/logs
# 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
# http://zookeeper.apache.org/doc/current/zookeeperAdmin.html#sc_maintenance
#
# The number of snapshots to retain in dataDir
autopurge.snapRetainCount=1
# Purge task interval in hours
# Set to "0" to disable auto purge feature
autopurge.purgeInterval=1
在 bin 目录下启动服务,并进入 cli 模式:
$ ./zkServer.sh start
$ ./zkCli.sh
基本的命令行操作:
# 创建节点 /root,值为空
[zk: localhost:2181(CONNECTED) 0] create /root ""
# 创建节点 /root/redis,值为 "m1c2"
[zk: localhost:2181(CONNECTED) 1] create /root/redis "m1c2"
# 查询节点 /root/redis 的值
[zk: localhost:2181(CONNECTED) 2] get /root/redis
# 设置节点 /root/redis 的值为 "m3c4"
[zk: localhost:2181(CONNECTED) 3] set /root/redis "m3c4"
# 删除节点 /root/redis
[zk: localhost:2181(CONNECTED) 4] delete /root/redis
# 显示节点 /root/redis 的子节点
[zk: localhost:2181(CONNECTED) 5] ls /root/redis
# 递归删除节点 /root/redis 及其子节点
[zk: localhost:2181(CONNECTED) 6] rmr /root/redis
停止服务的话命令是:
(先 Ctrl+c 退出 Cli 模式)
$ ./zkServer.sh stop
当然命令行只是便于理解和调试,真正注册和使用都是通过 C API 进行的,下一篇开始总结 C API 的使用方法和穿插一些高级概念。
网友评论