zookeeper使用篇-Zookeeper系统核心模型

this.version=version;
this.cversion=cversion;
this.aversion=aversion;
this.ephemeralOwner=ephemeralOwner;
this.dataLength=dataLength;
this.numChildren=numChildren;
this.pzxid=pzxid;
}

}

可以看到在Stat类的定义中,定义了很多变量用来存储不同的数据,而这些变量分别代表什么意思,有什么作用,接下来我们来对这些变量进行说明:

czxid

czxid代表Create ZXID,即代表着当前zookeeper节点创建的时候分配的事务ID,并且当前ID在创建完成以后不会再变更

mzxid

mzxid代表Modified ZXID,即代表着当前节点每一次触发变更操作的时候分配的事务ID,这里保存的是最后一次变更的时候分配的事务ID。

ctime

ctime代表Create time,与czxid搭配使用,即在创建当前节点的时候,记录创建的时间

mtime

mtime代表Modified time,与mzxid搭配使用,即会记录最后一次节点变更操作的时间

version

version代表当前节点的版本号

cversion

cversion代表当前节点中创建的子节点的版本号

aversion

aversion代表当前节点中ACL权限相关的版本号

ephemeralOwner

ephemeralOwner用来保存创建节点的时候生成的会话sessionId,如果当前节点是持久化节点,这个值一般为0(0x0)

dataLength

dataLength保存了当前节点中存储的数据对应的字节长度

numChildren

numChildren中保存了当前节点中创建的子节点的个数

pzxid

pzxid保存了该节点的子节点列表中最后一次被修改的时候生成的事务ID,需要注意的是这里只有子节点列表变化才会重新生成pzxid,如果某个子节点内容修改等操作并不会生成新的pzxid

节点的版本控制

从stat类的定义中,我们看到,在ZNode中,存在多种事务操作的ID,但是zk是如何保证每次事务操作的正确性和稳定的呢?这个时候我们不禁要考虑分布式场景下一个概念–锁,在分布式系统中,一般事务操作,都要保证排他性,而主流的锁方案分为悲观锁乐观锁两种。悲观锁具有强烈的独占和排他性,但是整个处理过程中,数据会完全被锁定,其他的事务对该数据将做不了任何操作,哪怕是读取数据的操作,直到事务操作结束释放悲观锁为止。但是在分布式场景下,更多的操作是读取共享的数据,如果使用悲观锁,则会造成大量的数据被锁定,造成性能大幅度下降。因此乐观锁的概念出现,在乐观锁中的绝大多数操作都是不对数据加锁的,而是在更新操作之前,去检查当前事务读取的数据与即将要修改的数据是否一致,从而确定是否在读取完数据到更新数据之前的过程中,有木有别的事务对该数据进行了修改操作。如果发现已经被更新了,则回滚当前事务操作,如果没有修改则执行当前的事务。在JDK中,乐观锁的一个典型实现则是利用CAS理论实现的,而Zookeeper也基于类似的实现方案,在每次事务操作之前,都会在PrepRequestProcessor处理器中的setData数据更新操作之前,进行一次版本检查操作,如下:

int newVersion = checkAndIncVersion(nodeRecord.stat.getVersion(), setDataRequest.getVersion(), path);

checkAndIncVersion方法如下:

private static int checkAndIncVersion(int currentVersion, int expectedVersion, String path)
throws KeeperException.BadVersionException {
//判断当前请求的版本不是-1,并且与原来的版本号不同时,则抛出异常,其他情况下则将版本号+1
if (expectedVersion != -1 && expectedVersion != currentVersion) {
throw new KeeperException.BadVersionException(path);
}
return currentVersion + 1;
}

通知机制Watcher

在前面的文章中,我们学习了Zookeeper的发布订阅功能的实践,同时我们也知道zk中存在多种监听通知,可以实现一对一,一对多等不同的通知机制。而zk中的watcher注册和通知过程如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

从这我们可以看出,整个Watcher机制中,主要包括watcherManager、客户端线程以及Zookeeper服务端三部分。大概的过程为客户端在朝服务器注册Watcher的同时,将watcher对象存储在客户端的WatcherManager中。当Zookeeper服务端触发了Watcher事件后,会向客户端发送通知,客户端线程则是从WatcherManager中取出Watcher对象来执行对应的逻辑。

Watcher接口

在Zookeeper中,Watcher接口表示一个标准的事件处理器。定义了对应的逻辑,其中KeeperStateEventType两个枚举类型的属性分别代表了通知的状态以及通知的事件类型,并且在Watcher接口中,定义了一个方法作为触发通知以后的逻辑处理方法:

process(WatchedEvent event),接下来我们来看看这两个核心的枚举类及其参数

KeeperState

KeeperState定义了Watcher事件的所有状态类型,代码如下:

public enum KeeperState {
@Deprecated
Unknown (-1), //未知状态,已经废弃
Disconnected (0),//断开连接
@Deprecated
NoSyncConnected (1),//没有连接,已经废弃
SyncConnected (3),//已经连接
AuthFailed (4),//权限异常
ConnectedReadOnly (5),//当前连接仅仅支持读操作
SaslAuthenticated(6),
Expired (-112),
Closed (7);//关闭连接

}

EventType

除了KeeperState以外,EventType代表了通知的类型,代码如下:

public enum EventType {
None (-1),//未知
NodeCreated (1),//创建节点成功通知
NodeDeleted (2),//节点移除通知
NodeDataChanged (3),//当前节点数据变化通知
NodeChildrenChanged (4),//子节点列表变化通知
DataWatchRemoved (5),
ChildWatchRemoved (6);
}

而在Zookeeper开发过程中,往往是两种类型参数组合返回,我们将常见的场景通知和组合列成表格,大概如下:

KeeperStateEventType触发场景
SyncConnectedNone建立连接成功
NodeCreated节点被创建
NodeDeleted节点被删除
NodeDataChanged节点内容变化
NodeChild renChanged节点所属子节点列表变化
DisconnectedNone断开连接
ExpiredNone超时
AuthFailedNone1.错误的Scheme进行权限检查 2.SASL权限检查失败
ACL权限操作

在Zookeeper中,提供了ACL权限机制来保障节点及对应数据的安全,但是需要注意的是Zookeeper中的ACL机制和传统的ACL并不一样,分别分为:权限模式(Scheme)、授权对象(ID)和权限(Permission),通常是以Scheme:ID:Permission方式组合成一个有效的ACL信息。接下来我们具体的学习这三种组成模块:

权限模式—Scheme

权限模式在Zookeeper中来确定权限验证过程中的校验策略。常见的策略有四种:

IP

IP模式一般通过IP地址进行粗粒度的权限控制,例如"ip:192.168.1.1/24"代表是192.168.1.*这个网段的IP进行的权限控制。

Digest

Digest是使用最多的一种权限模式,基于传统的"username:password"模式来控制对应的权限,当我们使用Digest方式来验证权限的时候,Zookeeper中先后两次进行编码处理,分别是SHA-1和BASE64算法,加密过程的实现在DigestAuthenticationProvider 类的

generateDigest(String idPassword)方法中进行封装

World

World模式属于一种开放的权限模式,此模式下几乎没有任何权限控制,所有用户都可以随意对任何节点进行操作

Super

在Zookeeper中存在一个超级管理员的模式,此模式不需要主动设置,在任何其他的权限策略下都可以使用,称之为Super权限,一旦获取了Super权限,即拥有了超级管理员权限,可以对所有的节点进行任意操作。

授权对象–ID

授权对象指的是权限所在的用户或者指定的权限实体,而在不同的模式下,授权对象都是不同的,各个权限模式与授权对象的关系如下:

权限模式授权对象
IP通常是一个ip或者一个ip段,例如192.168.1.1
Digest自定义的,一般为"username:password"
Worldanyone
Super与Digest一样,需要指定一个超级管理员信息

权限–Permission

权限即指的是经过权限模式认证后的被允许的操作,在Zookeeper中,权限操作分为五大类:

  • Create©:数据节点的创建权限,并且允许创建子节点
  • Delete(D):允许删除该节点的子节点
  • Read®:允许对该数据节点进行读取,也可以获取子节点列表、读取子节点等
  • Write(W):数据节点的更新权限,允许对该节点内容修改
  • Admin(A):数据节点的管理权限,允许对其设置ACL权限操作
实现自定义权限控制器

一般开发中,Zookeeper自带的权限操作已经满足日常使用,但是如果需要特殊的权限控制操作,Zookeeper同样支持自定义一个权限控制器,在Zookeeper中,权限主要在org.apache.zookeeper. server.auth.AuthenticationProvider接口中定义,其代码定义如下:

public interface AuthenticationProvider {
String getScheme();

KeeperException.Code handleAuthentication(ServerCnxn cnxn, byte authData[]);

boolean matches(String id, String aclExpr);

boolean isAuthenticated();

boolean isValid(String id);
}

我们需要实现自定义的权限控制器只要实现当前接口,在实现完毕以后,我们将该自定义的权限控制器注册到Zookeeper服务中去,而注册的方式有两种:

1.系统属性配置

在Zookeeper启动的时候,在启动参数中指定:

-Dzookeeper.authProvider.l=xxx.MyauthProvider

2.配置文件方式

Zookeeper中的zoo.cfg配置文件中可以添加如下的配置:

authProvider.l=xxx.MyauthProvider

Super模式使用

在Zookeeper使用过程中,往往存在一个场景,即原来节点的创建者设置了ACL权限,但是这个创建者已经不再使用了,而其他的客户端想要使用该节点,该怎么做呢?这个时候就需要Super模式的用户出马了!使用超级管理员权限,具体的步骤如下:

1.在Zookeeper启动的时候添加系统属性:

-Dzookeeper.DigestAuthenticationProvider. superDigest=root:kWN6aNSbjcKWPqjiV7c
gON24raU=

总结

现在新技术层出不穷,如果每次出新的技术,我们都深入的研究的话,很容易分散精力。新的技术可能很久之后我们才会在工作中用得上,当学的新技术无法学以致用,很容易被我们遗忘,到最后真的需要使用的时候,又要从头来过(虽然上手会更快)。

我觉得身为技术人,针对新技术应该是持拥抱态度的,入了这一行你就应该知道这是一个活到老学到老的行业,所以面对新技术,不要抵触,拥抱变化就好了。

Flutter 明显是一种全新的技术,而对于这个新技术在发布之初,花一个月的时间学习它,成本确实过高。但是周末花一天时间体验一下它的开发流程,了解一下它的优缺点、能干什么或者不能干什么。这个时间,并不是我们不能接受的。

如果有时间,其实通读一遍 Flutter 的文档,是最全面的一次对 Flutter 的了解过程。但是如果我们只有 8 小时的时间,我希望能关注一些最值得关注的点。

(跨平台开发(Flutter)、java基础与原理,自定义view、NDK、架构设计、性能优化、完整商业项目开发等)


《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》点击传送门,即可获取!
的了解过程。但是如果我们只有 8 小时的时间,我希望能关注一些最值得关注的点。

(跨平台开发(Flutter)、java基础与原理,自定义view、NDK、架构设计、性能优化、完整商业项目开发等)

[外链图片转存中…(img-yUs4I9rU-1714802640018)]
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》点击传送门,即可获取!

  • 19
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值