zookeeper原理详解

182 阅读4分钟

这是我参与8月更文挑战的第10天,活动详情查看:8月更文挑战

ZooKeeper 是 Apache 软件基金会的一个软件项目,它为大型分布式计算提供开源的分布式配置服务、同步服务和命名注册。

ZooKeeper 的架构通过冗余服务实现高可用性。

Zookeeper 的设计目标是将那些复杂且容易出错的分布式一致性服务封装起来,构成一个高效可靠的原语集,并以一系列简单易用的接口提供给用户使用。

一个典型的分布式数据一致性的解决方案,分布式应用程序可以基于它实现诸如数据发布/订阅、负载均衡、命名服务、分布式协调/通知、集群管理、Master 选举、分布式锁和分布式队列等功能。

ZooKeeper数据结构

ZooKeeper的数据结构,跟Unix文件系统非常类似,可以看做是一颗,每个节点叫做ZNode。每一个节点可以通过路径来标识,结构图如下:

那ZooKeeper这颗"树"有什么特点呢??ZooKeeper的节点我们称之为Znode,Znode分为两种类型:

  • 短暂/临时(Ephemeral) :当客户端和服务端断开连接后,所创建的Znode(节点)会自动删除
  • 持久(Persistent) :当客户端和服务端断开连接后,所创建的Znode(节点)不会删除

ZNode

这个应该算是Zookeeper中的基础,数据存储的最小单元。在Zookeeper中,类似文件系统的存储结构,被Zookeeper抽象成了树,树中的每一个节点(Node)被叫做ZNode。ZNode中维护了一个数据结构,用于记录ZNode中数据更改的版本号以及ACL(Access Control List)的变更。

有了这些数据的版本号以及其更新的Timestamp,Zookeeper就可以验证客户端请求的缓存是否合法,并协调更新。

而且,当Zookeeper的客户端执行更新或者删除操作时,都必须要带上要修改的对应数据的版本号。如果Zookeeper检测到对应的版本号不存在,则不会执行这次更新。如果合法,在ZNode中数据更新之后,其对应的版本号也会一起更新。 接下来我们来详细看一下这个维护版本号相关数据的数据结构,它叫Stat Structure,其字段有:

字段释义
czxid创建该节点的zxid
mzxid最后一次修改该节点的zxid
pzxid最后一次修改该节点的子节点的zxid
ctime从当前epoch开始到该节点被创建,所间隔的毫秒
mtime从当前epoch开始到该节点最后一次被编辑,所间隔的毫秒
version当前节点的改动次数(也就是版本号)
cversion当前节点的子节点的改动次数
aversion当前节点的ACL改动次数
ephemeralOwner当前临时节点owner的SessionID(如果不是临时节点则为空)
dataLength当前节点的数据的长度
numChildren当前节点的子节点数量

监听器

在上面我们已经简单知道了ZooKeeper的数据结构了,ZooKeeper还配合了监听器才能够做那么多事的。

常见的监听场景有以下两项:

  • 监听Znode节点的数据变化
  • 监听子节点的增减变化

图片.png

集群管理

1.是否有机器退出

所有机器约定在父目录GroupMembers下创建临时目录节点,然后监听父目录节点的子节点变化消息。一旦有机器挂掉,该机器与 zookeeper的连接断开,其所创建的临时目录节点被删除,所有其他机器都收到通知:某个兄弟目录被删除,于是,所有人都知道了。新机器加入 也是类似,所有机器收到通知:新兄弟目录加入,highcount又有了

2.选举master

所有机器创建临时顺序编号目录节点,每次选取编号最小的机器作为master就好。

4.分布式锁

锁服务可以分为两类,一个是保持独占,另一个是控制时序。

对于第一类,我们将zookeeper上的一个znode看作是一把锁,通过createznode的方式来实现。所有客户端都去创建 /distribute_lock 节点,最终成功创建的那个客户端也即拥有了这把锁。厕所有言:来也冲冲,去也冲冲,用完删除掉自己创建的distribute_lock 节点就释放出锁。

​ 对于第二类, /distribute_lock 已经预先存在,所有客户端在它下面创建临时顺序编号目录节点,和选master一样,编号最小的获得锁,用完删除,依次方便。