Zookeeper笔记整理

Zookeeper简介

Zookeeper常见的应用场景

  • 维护配置信息-----将配置信息保存在Zookeeper节点中
  • 分布式锁服务------创建临时有序节点,排序,当前节点监听上一临时节点,若上一节点删除,则相当于获得锁
  • 集群管理
  • 生成分布式唯一 id------创建临时有序节点,根据节点名称后的唯一数字来创建唯一ID

Zookeeper的设计目标

  1. 高性能:Zookeeper将全量数据存储在内存中,并直接服务于客户端的所有非事务请求,尤其适用于以读为主的应用场景
  2. 高可用:Zookeeper以集群的方式提供服务,每台机器都会在内存中维护当前的服务器状态,并且每台机器之间都相互保持着通信,只要集群超过一半的机器都能够正常工作,那么集群局能够正常对外服务
  3. 严格顺序访问:对于来自客户端的每个更新请求,Zookeeper都会分配一个全局唯一的递增编号,这个编号反映了所有事务操作的先后顺序

Zookeeper的数据模型

​ Zookeeper的数据节点可以视为树状结构(和Linux类似)树中的每个节点被称为ZNode,一个ZNode可以有多个子节点,ZNode兼具文件和目录两种特点,既像文件一样维护着数据、元信息、ACL、时间戳等数据结构,又像目录一样可以作为路径标识的一部分

在这里插入图片描述

一个ZNode大体分为3各部分

  • 节点的数据:即ZNode data,其关系就像java map中的(key,value)的关系
  • 节点的子节点children
  • 节点的状态stat:用来描述当前节点的创建、修改记录、包括cZxid、ctime等

节点状态stat的属性

​ 在Zookeeper shell中使用get命令查看指定路径节点的data、stat信息

其属性说明:

  • cZxid:数据节点创建时的事务ID

  • ctime:数据节点创建时的时间

  • mZxid:数据节点最后一次更新时的时间

  • pZxid:数据节点的子节点最后一次被修改时的事务ID

  • cversion:子节点的更改次数

  • dataVersion:节点数据的更改次数

  • aclVersion:节点ACL的更改次数

  • ephemeralOwner:如果节点是临时节点,则表示创建该节点的会话SessionID,如果节点是持久节点,则该属性为0

  • dataLength:数据内容的长度

  • numChildren:数据节点当前子节点的个数

    若Zxid1小于Zxid2,则Zxid1的更改发生在Zxid2之前

节点类型

​ Zookeeper中节点有两种,分别为临时节点和永久节点,节点类型在创建时即被确定,并且不能改变

  • 临时节点:该节点的生命周期依赖于创建他们的会话,一旦会话结束,临时节点将被自动删除,当然也可手动删除,虽然每个临时节点都会绑定到一个客户端会话,但他们对所有客户端还是可见的,另外,Zookeeper的临时节点不允许拥有子节点
  • 持久节点:该节点的生命周期不依赖于会话,并且只有在客户端显示执行删除操作时候,他们才能被删除
Zookeeper常用Shell命令
  • 新增节点
create [-s] [-e] path data  #其中-s为有序节点,-e为临时节点

​ 例如:创建持久化节点并写入数据,

create /Hadoop "123456"

​ 注:创建持久化有序节点,此时创建的节点名为指定节点名+自增序号,例如

create -s /a "aaaa"  #相当于create /a00000...(即a+自增序号)

​ 创建临时节点,临时节点会在会话过期后删除,例如:

create -e /tmp "tmp"

​ 创建临时有序节点,临时节点也会在会话过期后删除

create -s -a /aa "aaa"
  • 更新节点

    set path  data [version]
    

    更新节点的命令是set,可以直接进行修改,如

set /Hadoop "345"

​ 也可以基于版本号进行更改,此时类似于乐观锁机制,当你传入数据版本号(dataVersion)和当前节点的数据版本号不符合,Zookeeper就会拒绝更改,如:

set /Hadoop "1234" 1
  • 删除节点

    删除节点语法如下

delete path [version]

​ 和更新节点数据一样,也可传入版本号,当你传入数据版本号[dataVersion]和当前节点数据版本号符合时,Zookeeper才会执行删除操作

delete /Hadoop 1

注:要想删除某个节点及其所有后代节点,可以使用递归删除,命令为 rmr path.

  • 查看节点
get path
  • 查看节点状态

可以使用stat命令来查看节点状态,它的返回值和get命令类似,但不会返回节点数据

stat path
  • 查看节点列表
ls path 
ls2 path
#查看节点列表有上述两条命令,ls2 path 是ls path 的增强,不仅可以查看指定路径下的所有节点,还可查看当前节点信息
  • 监听器get path watch
get path watch
#使用此命令注册的监听器能够在节点内容发生改变的时候,向客户端发出通知,注意的是,Zookeeper的触发器是一次性的(one-time trigger),即触发一次就会立即失效
  • 监听器stat path watch
stat path watch
#使用此命令注册的监听器能够在节点状态发生改变时,向客户端发出通知
  • 监听器ls/ls2 path watch
ls path watch 
ls2 path watch
#使用上述节点注册的监听器能够监听该节点下所有子节点的增加和删除操作
Zookeeper的ACL权限控制

概述

​ Zookeeper类似文件系统,client可以创建节点、更新节点、删除节点。Zookeeper的access control list 访问控制列表可以控制节点的权限

​ ACL权限控制,使用scheme:id:permission来标识,主要涵盖三个方面:

  • 权限模式(scheme):授权的策略
  • 授权的对象(id):授权的对象
  • 权限(permission):授予的权限

其特性如下:

  • Zookeeper的权限控制是基于每个ZNode节点,需要对每个节点设置权限
  • 每个ZNode支持设置多种权限控制方案和多个权限
  • 子节点不会继承父节点的权限,客户端无权访问某节点,但可能可以访问他的子节点

权限模式

描述方案
world只有一个用户:anyone,代表登录Zookeeper所有人
ip对客户端使用IP地址认证
auth使用已添加认证的用户认证
digest使用”用户名:密码“方式认证

授权的对象

​ 给谁授予权限

​ 授权对象id是指,权限赋予的实体,例如:IP地址或用户

授予的权限

​ create、delete、read、write、admin也就是增、删、查、改、管理权限。这五种简写为cdrwa,注意:这5中权限中,delete是指对子节点的删除权限,其他四种权限指对自身节点的操作权限

权限ACL简写描述
createc可以创建子节点
deleted可以删除子节点(即下一级节点)
readr可以读取节点数据及显示子节点列表
writew可以设置节点数据
admina可以设置节点访问控制列表权限

授权的相关命令

命令使用方式描述
getAclgetAcl 读取ACL权限
setAclsetAcl 设置ACL权限
addauthaddauth 添加认证用户

world授权模式

setAcl  <path> world:anyone:<acl>

ip授权模式

setAcl  <path> ip:<ip>:<acl>

Auth授权模式

addauth digest <user>:<password> #添加认证用户
setAcl <path> auth:<user>:<acl>

Digest授权模式

setAcl <path> digest:<user>:<password>:<acl>

上文中的密码是经过SHA1即base64处理的密文,在SHELL中可以通过以下命令计算:

echo -n <user>:<password> | openssl dgst -binary -sha1 | openssl base64
Zookeeper java-api

Znode 是Zookeeper集合的核心组件,Zookeeper api提供了操作ZNode的细节

客户端应该遵循以下步骤,与Zookeeper服务器进行清晰和干净的交互

  • 连接到Zookeeper服务器,Zookeeper为客户端分配会话ID
  • 定期向服务器发送心跳,否则Zookeeper服务器将过期会话ID,客户端需要重新连接
  • 只要会话ID处于活动状态,就可以获取/设置ZNode
  • 所有任务完成后,断开与Zookeeper服务器的连接,如果客户端长时间不活动,则Zookeeper服务器将自动断开连接

连接Zookeeper

Zookeeper(String connectionString ,int sessionTimeout,Watcher watcher)
  • connectionString -----Zookeeper主机
  • sessionTimeout ------会话超时(以毫秒为单位)
  • watcher -----------实现“监视器”对象,Zookeeper集合会通过监视器对象返回连接状态
...
    //计数器对象
CountDownLatch countDownLatch=new CountDownLatch(1);
//arg1:服务器的IP和端口
//arg2:客户端与服务器之间的会话超时时间,以毫秒为单位
//arg3:监视器对象
Zookeeper zooKeeper =new Zookeeper("192.168.***.***:***",5000,new Watcher(){
    public void process(WatchedEvent event){
        if(event.getState()==Event.KeeperState.SyncConnected){
         conutDownLatch.countDown();   
        }
    }
});
//由于连接是异步连接,所以主线程阻塞等待连接对象创建成功
countDownLatch.await();
....
zooKeeper.close();
.....

新增节点

//同步方式
create(String path,byte[] data,List<ACL>acl,CreateMode createMode);
//异步方式
create(String path,byte[] data,List<ACL>acl,CreateMode createMode,AsyncCallback.StringCallback callBack,Object ctx);
  • path -Znode路径,例如:/node1/node2/node3
  • data --要存储在指定ZNode路径的数据
  • acl --要创建节点的访问控制列表,Zookeeper api提供一个静态接口ZooDefs.Ids来获取一些基本的acl列表,如:ZooDefs.Ids.OPEN_ACL_UNSAFE返回打开ZNode的ACL列表
  • createMode --节点类型,这是一个枚举
  • callBack —异步回调接口
  • ctx----传递上下文参数
//连接Zookeeper
...
    //arg1:节点的路径
    //arg2:节点的数据
    //arg3:权限列表  world:anyone:cdrwa  READ_ACL_UNSAFE------>world:anyone:r
    //arg4:节点类型  持久化节点
zooKeeper.create("/create/node1","node1".getBytes(),ZooDefs.Ids.OPEN_ACL_UNSAFE,CreateMode.PERSISTENT);
//异步创建
zooKeeper.create("/create/node1","node1".getBytes(),ZooDefs.Ids.OPEN_ACL_UNSAFE,CreateMode.PERSISTENT,new AsyncCallback.StringCallback(){
    public void processResult(int rc,String path,Object ctx,String name){
        //0代表创建成功
        System.out.println("rc");
        //节点的路径
         System.out.println("path");
         System.out.println("name");
        //上下文参数
         System.out.println("ctx");
    }
},"this is a node");
......
    

更新节点

//同步方式
setData(String path,bytes[] data,int version);
//异步方式
setData(String path,bytes[] data,int version,AsynCallback.statCallback callBack,Object ctx);
  • path --znode路径
  • data —要存储在指定ZNode路径中的数据
  • version --znode的当前版本,每当数据更改时,Zookeeper会更新ZNode的版本号
  • callBack:异步回调接口
  • ctx --传递上下文参数
//同步更新
....
    //arg1:节点的路径
    //arg2:修改的数据
    //arg3:数据的版本号,-1代表版本后不参与更新
setData(String "/set/node1","node1".getBytes(),-1);
....
//异步更新
....

删除节点

//同步方式
delete(String path,int version);
//异步方式
delete(String path,int version,AsyncCallback.voidCallback callBack,Object ctx);
  • path —ZNode路径
  • version --ZNode的当前版本
  • callBack --异步回调接口
  • ctx —传递上下文参数

查看节点

//同步方式
getData(String path,boolean b,Stat stat);
//异步方式
getData(String path,boolean b,AsyncCallback.DataCallback callBack,Object ctx);
  • path —ZNode路径
  • b —是否使用连接对象中注册的监视器
  • stat --返回ZNode的元素据
  • callBack —异步回调接口
  • ctx —传递上下文参数

查看子节点

//同步方式
getChildren(String path,boolean b);
//异步方式
getChildren(String path,boolean b,AsyncCallback.ChildrenCallback callBack,Object ctx );
  • path --znode路径
  • b ----是否使用连接对象中注册的监视器
  • callBack —异步回调接口
  • ctx —传递上下文参数

检查节点是否存在

//同步方法
exists(String path,boolean b);
//异步方法
exists(String path,boolean b,AsyncCallback.StatCallback callback,Object ctx);
  • path --znode路径
  • b ----是否使用连接对象中注册的监视器
  • callBack —异步回调接口
  • ctx —传递上下文参数
watcher(时间监听机制)

watcher实现由三部分组成:

  • Zookeeper服务端

  • Zookeeper客户端

  • 客户端的ZKWatchManager对象

    客户端将Watcher注册到服务端,同时将watcher对象保存在客户端的Watch管理中,当Zookeeper服务端监听的数据状态发生变化时,服务端会主动通知客户端,接着客户端的Watch管理器会触发相关watcher来回调相应处理逻辑,从而完成整体的数据发布/订阅流程

在这里插入图片描述

watcher特性

特性说明
一次性watcher是一次性的,一旦触发就会移除,再次使用时需要重新注册
客户端顺序回调watcher回调是顺序串行化执行的,只有回调后客户端才能看到最新的数据状态,一个watcher回调逻辑不应该太多,以免影响别的watcher执行
轻量级WatchEvent是最小的通信单元,结构上只包含通知状态、事件类型和节点路径,并不会告诉数据节点变化前后的具体内容
时效性watcher只有在当前session彻底失效时才会无效,若在session有效期内快速重连成功,则watcher依然存在,仍可接受通知

Watcher通知状态(KeeperState)

​ keeperstate是客户端与服务器连接状态发生变化时对应的通知类型,其是一个枚举类,其枚举属性如下:

枚举属性说明
SyncConnected客户端与服务器正常连接时
Disconnected客户端与服务器断开连接时
Expired会话Session失效时
AuthFailed身份认证失败时

Watcher事件类型

​ EventType是数据节点(ZNode)发生变化时对应的通知类型。EventType变化时KeeperState永远处于SyncConnectedted通知状态下,当KeepState发生变化时,EventType永远为None,EventType是一个枚举类,其枚举属性为:

枚举属性说明
None
NodeCreateWatcher监听的数据节点被创建时
NodeDeleteWatcher监听的数据节点被删除时
NodeDataChangedWatcher监听的数据节点内容发生变更时(无论内容数据是否变化)
NodeChildrenChangedWatcher监听的数据节点的子节点列表发生变更时

注:客户端接受到的相关事件通知中只包含状态及类型等信息,不包括节点变化前后的具体内容,变化前的数据需业务自身存储,变化后的数据需调用get等方法获取

捕获相应的事件

​ 在Zookeeper中采用zk.getChildrenn(path,watch)/zk.exists(path,watch)、zk.getData(path,watch,stat)这些为某个ZNode注册监听

下表以node-x节点为例 ,说明调用的注册方法和可监听事件间的关系:

注册方式CreateChildrenChangedchangedDeleted
zk.exists("/node-x",watcher)可监控可监控可监控
zk.getData("/node-x",watcher)可监控可监控
zk.getChildren("/node-x",watcher)可监控可监控
集群

一致性协议----zab

zab协议的全称是Zookeeper Atomic Broadcast —Zookeeper原子广播)Zookeeper是通过zab协议来保证分布式事务的最终一致性

​ 基于zab协议,Zookeeper集群中的角色主要有以下三类,如下表所示:

在这里插入图片描述

zab广播模式工作原理,通过类似两阶段提交协议的方式解决数据的一致性:

在这里插入图片描述

  1. leader从客户端收到一个写请求
  2. leader生成一个新的事务并为这个事务生成一个唯一的ZXID
  3. leader将这个事务提议(propose)发送给所有的follower节点
  4. follower节点将收到的事务请求加入到历史队列(history queue)中,并发送ack给leader
  5. 当leader收到大多数follower(半数以上节点)的ack消息,leader会发送commit请求
  6. 当follower收到commit请求时,从历史队列中将事务请求commit

Zookeeper的leader选举

服务器状态:

  • looking:寻找leader状态,当服务器处于该状态时,他会认为当前集群中没有leader,因此需要进入leader选举状态:

  • leading:领导者状态,表明当前服务器角色是leader

  • following:跟随者状态,表明当前服务器角色是follower

  • observing:观察者状态,表明当前服务器角色是observer

leader选举流程:

observer角色及配置

observer角色特点

  1. 不参与集群的leader选举

  2. 不参与集群中写数据时的ack反馈

    为了使用observer角色,在任何想变成observer角色的配置文件中加入如下配置:

peerType=observer

​ 并在所有的server配置文件中,配置成observer模式的server的那行追加:observer

server.3=192.168.60.130:2282:3389:observer

Zookeeper api集群的连接

Zookeeper(String connectionString,int sessionTimeout,Watcher watcher)
  • connectionString ----Zookeeper集合主机
  • sessionTimeout-----会话超时(以毫秒为单位)
  • watcher ------实现“监视器”界面的对象,Zookeeper集合通过监视器对象返回连接状态
Zookeeper开源客户端Curator介绍

原生ZookeeperApi的不足

  1. 连接对象异步创建,需要开发人员自行编码等待
  2. 连接没有自动重连超时机制
  3. watcher一次注册生效一次
  4. 不支持递归创建树形节点

curator特点:

  1. 解决session会话超时重连
  2. watcher反复注册
  3. 简化开发api
  4. 遵循Fluent风格的api
  5. 提供分布式锁服务,共享计数器,缓存机制等

watcherApi

curator提供了两种watcher(cache)来监听节点变化

  • Node Cache:只是监听某一特定节点,监听节点的新增和修改
  • PathChildren Cache:监控一个ZNode的子节点,当一个子节点增加,更新,删除时,Path Cache会改变他的状态,会包含最新的子节点、子节点的数据和状态

分布式锁

  • InterProcessMutex:分布式可重入排它锁
  • InterProcessReadWriteLock:分布式读写锁

监控命令

Zookeeper支持某些特定的四字命令与其交互,用户在客户端可以通过Telnet或nc向Zookeeper提交相应的命令,常见四字命令如下表

命令描述
conf输出相关服务配置的详细信息,比如端口、zk数据及日志配置路径,最大连接数、session超时时间、serverld等
cons列出所有连接到这台服务器的客户端/会话的详细信息,包括”接受/发送“的包的数量,session id、操作延迟、最后操作执行等信息
crst重置当前这台服务器所有连接/会话的统计信息
dump列出未经处理的会话和临时节点
envi输出关于服务器环境详细信息
ruok测试服务器是否处于正确运行状态,如果正常返回”imok“,否则返回空
stat输出服务器的详细信息:接受/发送包数量、连接数、模式(leader/follower)、节点总数、延迟。所有客户端的列表
srst重置server状态
wchs列出服务器watches的简洁信息:连接总数、watching节点总数和watches总数
wchc通过session分组,列出watch的所有节点,它的输出是一个与watch相关的会话的节点列表
mntr列出集群的健康状态,包括“接受/发送”的包数量,操作延迟、当前服务模式(leader/follower)、节点总数、watch总数、临时节点总数

conf命令

#conf:输出相关的服务配置详细信息
encho conf | nc ip 端口
属性含义
clientPort客户端端口号
dataDir数据快照文件目录 默认情况下100000次事务操作生成一次快照
dataLogDir事务日志文件目录、生产环境中放在独立的磁盘上
tickTime服务器之间或客户端与服务器之间维持心跳的时间间隔(以毫秒为单位)
maxClientCnxns最大连接数
minSessionTimeout最小session超时minSessionTimeout=tickTime*2
maxSessionTimeout最大session超时maxSessionTimeout=tickTime*20
serverId服务器编号
InitLimit急群众的follower服务器(F)与leader服务器之间初始连接时能容忍的最多心跳数
syncLimit集群中的follower服务器(F)与leader服务器之间请求和应答之间能容忍的最多心跳数
electionAlg0:基于udp的LeaderElection ,1:基于udpde fastLeaderElection ,2:基于udp和认证的FastLeaderElection ,3:基于tcp的FastLeaderElection
electionPort选举端口
quorumPort数据通信端口
peerType是否为观察者 1为观察者

 |

| serverId | 服务器编号 |
| InitLimit | 急群众的follower服务器(F)与leader服务器之间初始连接时能容忍的最多心跳数 |
| syncLimit | 集群中的follower服务器(F)与leader服务器之间请求和应答之间能容忍的最多心跳数 |
| electionAlg | 0:基于udp的LeaderElection ,1:基于udpde fastLeaderElection ,2:基于udp和认证的FastLeaderElection ,3:基于tcp的FastLeaderElection |
| electionPort | 选举端口 |
| quorumPort | 数据通信端口 |
| peerType | 是否为观察者 1为观察者 |

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值