zookeeper系统模型

本文将从数据模型、节点特性、版本、监听器、ACL五方面来阐述zookeeper的系统模型。

1. 数据模型

zookeeper采用树形层次结构,树中的每个节点被称为znode。

                                    

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

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

2. 节点特性

节点类型

持久节点(PERSISTENT): 节点创建后一直存在,只能被显式删除;
持久顺序节点(PERSISTENT_SEQUENTIAL):同持久节点,且该节点创建子节点时,自动为子节点的命名末尾添加递增编号,用于记录下每个节点创建的先后顺序,这个编号的上限是整形的最大值;
临时节点(EPHEMERAL):生命周期和客户端的会话绑定,客户端会话失效后(非TCP断开)自动删除节点,这一特性也决定了临时节点不能包含子节点。
临时顺序节点(EPHEMERAL_SEQUENTIAL):同临时节点,且节点命名末尾自动添加递增编号;

znode包含文件和目录两种特性,既像文件一样维护着数据、元信息、ACL、时间戳等数据结构,又像目录一样可以作为路径标识的一部分。每个Znode由3部分组成:
① stat:维护Znode的状态信息;
② data:该Znode关联的数据;
③ acl:访问控制列表,用于控制Znode的访问权限(读写、创建、删除等);

stat存储的状态信息:
cZxid:创建Znode的事务ID;
ctime:Znode的创建时间;
mZxid:最后一次修改Znode的事务ID;
mtime:最近一次修改Znode的时间;
pZxid: Znode添加或删除子节点操作的事务ID;
cversion:Znode子节点更改次数;
dataVersion:Znode的数据更改次数;
aclVersion:Znode ACL的更改次数;
ephemeralOwner:临时节点所有者的session id,如果此节点为持久节点,则值为0;
dataLength:Znode数据长度;
numChildren:Znode子节点个数;

znode基本操作

create: 创建Znode (父Znode 必须已经存在);
delete: 删除Znode(该节点必须不包含任何子Znode );
exists: 测试Znode是否存在,如果存在则获取Znode状态信息;
getACL/setACL: 获取/设置Znode ACL权限;
getChildren: 获取子Znode的列表;
getData/setData: 获取/设置Znode data;
sync: 同步client和zookeeper的znode信息;

3. 版本

每个数据节点都有三个版本信息

版本类型    说明
version    当前数据节点数据内容的版本号
cversion    当前数据节点子节点的版本号
aversion    当前数据节点ACL变更版本号
以version为例:创建一个数据节点/zk-book这个节点的version=0(表示这个节点被更改过0次);当对这个节点的内容进行N次更改那么version=N;

悲观锁:

又被称作悲观并发控制(Pessimistic Concurrency Control,缩写“PCC),是数据库中一种非常典型且非常严格的并发控制策略。悲观锁具有强烈的独占性和排他特性,能够有效地避免不同事务对同一数据并发更新造成的数据一致性问题。

应用场景:

悲观锁策略适合解决那些对于数据库更新竞争十分激烈的场景,采用简单粗暴的悲观锁机制来解决并发控制问题。

乐观锁:

又被称作乐观并发控制(又名“乐观锁”,Optimistic Concurrency Control,缩写“OCC”)也是一种常见的并发控制机策略。它假设多用户并发的事务在处理时不会彼此互相影响,各事务能够在不产生锁的情况下处理各自影响的那部分数据。在提交数据更新之前,每个事务会先检查在该事务读取数据后,有没有其他事务又修改了该数据。如果其他事务有更新的话,正在提交的事务会进行回滚。

应用场景:

通常适用于数据并发竞争不大、事务冲突较少的应用场景。

在zookeeper中,version属性正式用来实现乐观锁机制的“写入校验”的。

4. 监听器

ZooKeeper允许客户端向服务端注册一个Watcher监听,当服务端的一些指定事件触发了这个Watcher,那么就会向指定客户端发送一个事件通知来实现分布式的通知功能。
典型应用场景:定义一个一对多的订阅关系,能够让多个订阅者同时监听某一个主题对象,当这个主题对象自身状态变化时,会通知所有订阅者,使他们能够做出相应的处理。

概述客户端在向zooKeeper服务器注册Watcher的同时,会将Watcher对象存储在客户端的WatchManager中。当zooKeeper服务器端触发Watcher事件后,会向客户端发送通知,客户端线程从WatchManager中取出对应的Watcher对象来执行回调逻辑。

接口类Watcher用于表示一个标准的事件处理器,其定义了事件通知的逻辑,包含KeeperState和EventType两个枚举类。分别代表了通知状态和事件类型。同一个事件类型在不同的通知状态中代表的含义有所不同。

回调方法process()

process()方法是Watcher接口中的一个回调方法,当zooKeeper向客户端发送一个Watcher事件通知后,客户端就会对相应的process()方法进行回调,从而实现对事件的处理。process()方法的定义如下:

abstract public void process(WatchedEvent event);

WatchedEvent包含了每一个事件的三个基本属性:

public class WatchedEvent {
  final private KeeperState keeperState;   //通知状态
  final private EventType eventType;   //事件类型
  private String path;  //节点路径

  ...

    /**
     *  Convert WatchedEvent to type that can be sent over network
     */
    public WatcherEvent getWrapper() {
        return new WatcherEvent(eventType.getIntValue(), 
                                keeperState.getIntValue(), 
                                path);
    }
}

WatcherEvent 实体和WatchedEvent

笼统地讲,两者表示的是同一个事物,都是对一个服务端事件的封装。不同的是,WatchedEvent是一个逻辑事件,用于服务端和客户端程序执行过程中所需的逻辑对象,而WatcherEvent因为实现了序列化接口,因此可以用于网络传输。
服务端在生成WatchedEvent事件之后,会调用getWrapper方法将自己包装成一个可序列化的WatcherEvent事件,以便通过网络传输到客户端。客户端在接收到服务端的这个事件对象后,首先会将WatcherEvent事件还原成一个WatchedEvent事件,并传递给process方法处理。

5. ACL

ACL(Access Control List) : zooKeeper作为一个分布式协调框架,其内部存储的都是一些关乎分布式系统运行时状态的元数据,尤其是一些涉及分布式锁、master选举和分布式协调等应用场景的数据,会直接影响基于zooKeeper进行构建的分布式系统的运行状态。因此,zooKeeper提供了一套完善的ACL权限控制机制来保障数据的安全,包含三个方面:权限模式(scheme),授权对象(ID),权限(permisssion)。

scheme

权限模式用来确定权限验证过程中使用的检验策略,zooKeeper中包括以下四种权限模式:
IP: IP模式通过IP地址来进行权限控制,例如配置了“ip:192.168.0.110”,即标签权限控制都是针对这个IP地址的(IP模式也支持按照网段的方式进行配置);
Digest:以"username:password"形式的权限标识来进行权限配置,便于区分不同应用来进行权限控制;
World:数据节点的访问权限对所有用户开放,即所有用户都可以在不进行任何权限校验的情况下操作ZooKeeper上的数据,它只有一个权限标识,即"world:anyone";
Super: 超级用户,可以对ZooKeeper上任意的数据节点进行任何操作;

备注:ZooKeeper 除以上4种默认权限模式外,还提供了特殊的权限控制插件体系,允许开发人员通过指定方式对ZooKeeper的权限精选扩展。

ID

授权对象指的是权限赋予的用户或一个指定实体,例如IP地址或是机器等。在不同的权限模式下,授权对象是不同的。

Permission

权限就是指那些通过权限检查后可以被允许执行的操作,所有对数据的操作权限分为以下五类:

CREATE(c): 数据节点的创建权限,允许授权对象在该数据节点下创建子节点;
DELETE(d): 子节点的删除权限,允许授权对象删除该数据节点的子节点;
READ(r): 数据节点的读取权限,允许授权对象访问该数据节点并读取其数据内容或子节点列表等;
WRITE(w): 数据节点的更新权限, 允许授权对象对该数据节点进行更新操作;
ADMIN(a): 数据节点的管理权限,允许授权对象对该数据节点进行ACL相关的设置操作;

 设置ACL

在数据节点创建时进行ACL权限的设置:

create [-s] [-e] path data acl
create -e /zk-book init digest:foo: MiGs3Eiy1pP4rvH1Q1N1wbP+oUF8=:cdrwa

对已经创建的数据节点进行ACL权限的设置:

set path acl
set /zk-book init digest:foo: MiGs3Eiy1pP4rvH1Q1N1wbP+oUF8=:cdrw

查看数据节点的ACL设置:

getAcl path
getAcl /zk-book

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值