Zookeeper 系统模型

数据模型

zookeeper 的视图结构和标准的Unix文件系统非常类似,但是没有引入传统文件系统中目录和文件等相关概念,而是使用了其特有的数据节点概念,我们称为Znode,Znode 是zookeeper中数据的最小单元,每个Znode上都可以保存数据,同时还可以挂载子节点,因此构成了一个层次化的命名空间,我们称为树。

Znode的节点路径标识方式和Unix文件系统路径非常相似,都是由一系列使用斜杠(/)进行分割的路径表示,开发人员可以向这个节点中写入数据,也可以在节点下面创建子节点。

在ZK中,事务是指能够改变ZK服务器状态的操作,我们称之为事务操作或更新操作,一般包括数据节点创建与删除,数据节点内容更新和客户端会话创建与失效等操作。对于每一个事务请求,ZK都会为其分配一个全局唯一的事务ID,用ZXID表示,通常是一个64位的数字,每一个ZXID对应一次更新操作,从这些ZXID可以间接地识别出ZK处理这些更新操作请求的全局顺序。

节点特性

ZK中,每个数据节点都是有生命周期的,其生命周期的长短取决于数据节点的节点类型,在ZK中,节点类型可以分为持久节点临时节点顺序节点三大类,具体在节点创建过程中,通过组合使用,可以生成以下四种组合类型节点类型。

  • 持久节点

    最常见类型,创建后,就会一直存在于ZK服务器上,直到有删除操作来主动清除这个节点。

  • 持久顺序节点

    基本特性与持久节点一样,额外的特性表现在顺序性上,在ZK上,每个父节点都会为它的第一级子节点维护一份顺序,用于记录下每个子节点创建的先后顺序,基于这个顺序特性,在创建子节点的时候,可以设置这个标记,那么在创建节点过程中,ZK会自动为给定节点加上一个数字后缀,作为一个新的,完整的节点名。

  • 临时节点

    临时节点生命周期与客户端会话绑定在一起,如果客户端会话失效,节点就会被自动清理掉。另外,不能基于临时节点来创建子节点,临时节点只能作为叶子节点。

  • 临时顺序节点

    同样在临时节点的基础上,加上了顺序的特性。

事实上,每个数据节点除了存储了数据内容外,还存储了数据节点本身的一些状态信息,也就是Stat对象的输出。包括了事务ID,版本信息和子节点个数等信息。

版本—保证分布式数据原子性操作

每个数据节点都具有三种类型的版本信息,对数据节点的任何更新操作都会引起版本号的变化,三种版本信息分别是version(当前数据节点数据内容的版本号),cversion(当前数据节点子节点的版本号),aversion(当前数据节点ACL变更版本号)

ZK中的吧版本概念表示的是对数据节点的数据内容,子节点列表,或是节点ACL信息的修改次数,即使前后两次变更并没有使得数据内容的值发生变化,version的值依然会变更。


先看分布式领域中最常见的一个概念,锁

悲观锁,又被称作悲观并发控制,是数据库中一种非常典型且非常严格的并发控制策略,适合解决那些对于数据更新竞争十分激烈的场景

乐观锁,在更新事务提交之前,每个事务都会检查当前事务读取数据后,是否有其他事务对该数据进行了修改,若有其他事务更新的话,那么提交的事务就需要回滚,所以适合并发竞争不大,事务冲突较少的场景。


ZK中,version属性正是用来实现乐观锁机制中的“写入校验”的,在ZK服务器的PreRequestProcessor 处理器类中,在处理每一个数据更新请求时,都会先对版本进行检查,获取当前请求的版本version,同时从数据记录nodeRecore中获取当前服务器上该数据的最新版本currentVersion。

watcher 数据变更的通知

ZK提供了分布式数据的发布、订阅功能,一个典型的发布订阅模型系统定义了一种一对多的订阅关系,能够让多个订阅者同时监听某一个主题对象,当这个主题对象自身状态变化时,会通知所有订阅者,使他们能够做出相应的处理。ZK中,引入了watcher 这种分布式的通知机制,ZK允许客户端向服务端注册一个watcher监听,当服务端的一些指定事件触发了这个watcher,那么就会向指定客户端发送一个事件通知来实现分布式的通知功能,

ZK的watcher机制主要包括客户端线程,客户端watcherManager,ZK服务器三部分,具体流程上,客户端在向ZK服务器注册watcher的同时,会将watcher对象存储在客户端的watcherManager中。当ZK服务器触发watcher事件后,会向客户端发送通知,客户端线程从watcherManager 中取出对应的Watcher 对象来执行回调逻辑。

工作机制

watcher机制,总的来说可以概括为以下三个过程,客户端注册Watcher,服务端处理Watcher和客户端回调watcher。

特性

一次性:一旦一个watcher被触发,ZK都会将其从对应的存储中移除。

客户端串行执行: 客户端watcher回调的过程是一个串行同步的过程,这保证了顺序。

轻量:网络开销和服务端内存开销都是非常廉价的。

ACL 保障数据的安全

ZK提供了一套完整的ACL权限控制机制来保障数据的安全。

三个方面理解ACL机制,分别是“权限模式”,授权对象和权限,通常使用“schema:id:permission 来标识一个有效的ACL信息。

权限模式 权限模式用来确定权限验证过程中使用的检验策略,有四种主要的权限模式,分别是IP,Digest(类似于username:password的形式)World,Super

IP模式指的是通过IP地址粒度来进行权限控制,例如配置了“ip:192.168.0.110”,即表示权限控制都是针对这个IP地址的,

Digest 是最常用的权限控制,其以类似于“username:password” 形式的权限标识来进行权限控制,便于区分不同应用来进行权限控制。

world 是最开放的一种权限控制模式,几乎没有任何作用,数据节点的访问权限对所有用户开放,即所有用户可以在不尽兴任何权限校验的情况下操作ZK上的数据。

Super 也就是超级用户,对ZK上的数据节点进行任何操作。

授权对象:ID 授权对象指的是权限授予的用户或一个指定实体,

权限 Permission 指通过权限检查后可以被允许执行的操作,有五大类,CREATE,DELETE,READ,WRITE,ADMIN