zookeeper --- 基础篇
一、zookeeper简介
1.1、什么是zookeeper
zookeeper官网:https://zookeeper.apache.org/
大数据生态系统里的很多组件的命名都是某种动物或者昆虫,他是用来管 Hadoop(大象)、Hive(蜜蜂)、Pig(小 猪)的管理员。顾名思义就是管理大数据生态系统各组件的管理员。简称zk
1.2、zookeeper应用场景
zooKeeper是一个经典的分布式数据一致性解决方案,致力于为分布式应用提供一
个高性能、高可用,且具有严格顺序访问控制能力的分布式协调存储服务。
- 维护配置信息
- 分布式锁服务
- 集群管理
- 生成分布式唯一ID
1.2.1、维护配置信息
java编程经常会遇到配置项,比如数据库的url、schema、user和password
等。通常这些配置项我们会放置在配置文件中,再将配置文件放置在服务器上当需要更
改配置项时,需要去服务器上修改对应的配置文件。但是随着分布式系统的兴起,由于
许多服务都需要使用到该配置文件,因此又必须保证该配置服务的高可用性(high
availability)和各台服务器上配置数据的一致性。通常会将配置文件部署在一个集群上,
然而一个集群动辄上千台服务器,此时如果再一台台服务器逐个修改配置文件那将是非
常繁琐且危险的的操作,因此就需要一种服务,能够高效快速且可靠地完成配置项的更
改等操作,并能够保证各配置项在每台服务器上的数据一致性。
zookeeper就可以提供这样一种服务,其使用Zab这种一致性协议来保证一致性。现在有很多开源项目使用zookeeper来维护配置,比如在hbase中,客户端就是连接一个zookeeper,获得必要的hbase集群的配置信息,然后才可以进一步操作。还有在开源的消息队列kafka中,也使用zookeeper来维护broker的信息。在alibaba开源的soa框架dubbo中也广泛的使用zookeeper管理一些配置来实现服务治理。
1.2.2、分布式锁服务
一个集群是一个分布式系统,由多台服务器组成。为了提高并发度和可靠性,多台服务器上运行着同一种服务。当多个服务在运行时就需要协调各服务的进度,有时候需要保证当某个服务在进行某个操作时,其他的服务都不能进行该操作,即对该操作进行加锁,如果当前机器挂掉后,释放锁并fail over 到其他的机器继续执行该服务。
1.2.3、集群管理
一个集群有时会因为各种软硬件故障或者网络故障,出现某些服务器挂掉而被移除集群,而某些服务器加入到集群中的情况,zookeeper会将这些服务器加入/移出的情况通知给集群中的其他正常工作的服务器,以及时调整存储和计算等任务的分配和执行等。此外zookeeper还会对故障的服务器做出诊断并尝试修复。
1.2.4、生成分布式唯一ID
在过去的单库单表型系统中,通常可以使用数据库字段自带的auto_increment属性来自动为每条记录生成一个唯一的ID。但是分库分表后,就无法在依靠数据库的auto_increment属性来唯一标识一条记录了。此时我们就可以用zookeeper在分布式环境下生成全局唯一ID。做法如下:每次要生成一个新Id时,创建一个持久顺序节点,创建操作返回的节点序号,即为新Id,然后把比自己节点小的删除即可
1.3、zookeeper的设计目标
zooKeeper致力于为分布式应用提供一个高性能、高可用,且具有严格顺序访问控制能力的分布式协调服务
-
高性能
- zooKeeper将全量数据存储在内存中,并直接服务于客户端的所有非事务请求,尤其适用于以读为主的应用场景
-
高可用
- zooKeeper一般以集群的方式对外提供服务,一般3 ~ 5台机器就可以组成一个可用的Zookeeper集群了,每台机器都会在内存中维护当前的服务器状态,并且每台机器之间都相互保持着通信。只要集群中超过一半的机器都能够正常工作,那么整个集群就能够正常对外服务
-
严格顺序访问
- 对于来自客户端的每个更新请求,ZooKeeper都会分配一个全局唯一的递增编号,这个编号反映了所有事务操作的先后顺序
二、zookeeper数据模型
zookeeper的数据节点可以视为树状结构(或者目录),树中的各节点被称为znode(即zookeeper node),一个znode可以有多个子节点。zookeeper节点在结构上表现为树状;使用路径path来定位某个znode,比如/ns-1/angyan/mysql/schema1/table1,此处ns-1、angyan、mysql、schema1、table1分别是根节点、2级节点、3级节点以及4级节点;其中ns-1是angyan的父节点,angyan是ns-1的子节点,angyan是mysql的父节点,mysql是angyan的子节点,以此类推。
znode,兼具文件和目录两种特点。既像文件一样维护着数据、元信息、ACL、时间戳等数据结构,又像目录一样可以作为路径标识的一部分。
那么如何描述一个znode呢?一个znode大体上分为3各部分:
- 节点的数据:即znode data(节点path, 节点data)的关系就像是java map中(key,value)的关系
- 节点的子节点children
- 节点的状态stat:用来描述当前节点的创建、修改记录,包括cZxid、ctime等节点状态stat的属性
节点类型
zookeeper中的节点有两种,分别为临时节点
和永久节点
。节点的类型在创建时即被确定,并且不能改变。
-
临时节点:该节点的生命周期依赖于创建它们的会话。一旦会话(Session)结束,临时节点将被自动删除,当然可以也可以手动删除。虽然每个临时的Znode都会绑定到一个客户端会话,但他们对所有的客户端还是可见的。另外,ZooKeeper的临时节点不允许拥有子节点。
-
持久化节点:该节点的生命周期不依赖于会话,并且只有在客户端显示执行删除操作的时候,他们才能被删除
三、zookeeper单机安装
当前测试系统环境centos7.3
jdk:jdk-8u131-linux-x64.tar.gz
zookeeper:zookeeper-3.4.10.tar.gz
1、在centos中使用root用户创建zookeeper用户,用户名:zookeeper 密码:zookeeper
useradd zookeeper
passwd zookeeper
2、zookeeper底层依赖于jdk,zookeeper用户登录后,根目录下先进行jdk的安装,jdk使用jdk-8u131-linux-x64.tar.gz版本,上传并解压jdk
//解压jdk
tar -xzvf jdk-8u131-linux-x64.tar.gz
3、配置jdk环境变量
// vim打开 .bash_profile文件
vi .bash_profile// 文件中加入如下内容
JAVA_HOME=/home/zookeeper/jdk1.8.0_131
export JAVA_HOMEPATH=$JAVA_HOME/bin:$PATH
export PATH// 使环境变量生效
. .bash_profile
4、检测jdk安装
// 敲如下命令,系统如图反馈说明安装成功
java -version
5、zookeeper使用zookeeper-3.4.10.tar.gz,上传并解压
// 解压zookeeper
tar -xzvf zookeeper-3.4.10.tar.gz
6、为zookeeper准备配置文件
// 进入conf目录
cd /home/zookeeper/zookeeper-3.4.10/conf
// 复制配置文件
cp zoo_sample.cfg zoo.cfg
// zookeeper根目录下新建data目录
mkdir data
// vi 修改配置文件中的dataDir
// 此路径用于存储zookeeper中数据的内存快照、及事物日志文件
dataDir=/home/zookeeper/zookeeper-3.4.10/data
7、启动zookeeper
// 进入zookeeper的bin目录
cd /home/zookeeper/zookeeper-3.4.10/bin
// 启动zookeeper
./zkServer.sh start//启动:zkServer.sh start
//停止:zkServer.sh stop
//查看状态:zkServer.sh status
四、zookeeper常用shell命令
4.1、新增节点
create [-s] [-e] path data #其中-s 为有序节点,-e 临时节点
创建持久化节点并写入数据:
create /hadoop "123456"
创建持久化有序节点,此时创建的节点名为指定节点名 + 自增序号
[zk: localhost:2181(CONNECTED) 2] create -s /a "aaa"
Created /a0000000000
[zk: localhost:2181(CONNECTED) 3] create -s /b "bbb"
Created /b0000000001
[zk: localhost:2181(CONNECTED) 4] create -s /c "ccc"
Created /c0000000002
创建临时节点,临时节点会在会话过期后被删除:
[zk: localhost:2181(CONNECTED) 5] create -e /tmp "tmp"
Created /tmp
创建临时有序节点,临时节点会在会话过期后被删除:
[zk: localhost:2181(CONNECTED) 6] create -s -e /aa 'aaa'
Created /aa0000000004
[zk: localhost:2181(CONNECTED) 7] create -s -e /bb 'bbb'
Created /bb0000000005
[zk: localhost:2181(CONNECTED) 8] create -s -e /cc 'ccc'
Created /cc0000000006
4.2、更新节点
更新节点的命令是 set ,可以直接进行修改,如下:
[zk: localhost:2181(CONNECTED) 3] set /hadoop "345"
cZxid = 0x4
ctime = Thu Dec 12 14:55:53 CST 2019
mZxid = 0x5
mtime = Thu Dec 12 15:01:59 CST 2019
pZxid = 0x4
cversion = 0
dataVersion = 1
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 3
numChildren = 0
也可以基于版本号进行更改,此时类似于乐观锁机制,当你传入的数据版本号(dataVersion) 和当前节点的数据版本号不符合时,zookeeper 会拒绝本次修改:
[zk: localhost:2181(CONNECTED) 10] set /hadoop "3456" 1
version No is not valid : /hadoop
4.3、删除节点
删除节点的语法如下:
delete path [version]
和更新节点数据一样,也可以传入版本号,当你传入的数据版本号 (dataVersion)和当前节点的数据版本号不符合时,zookeeper 不会执行删除操作。
[zk: localhost:2181(CONNECTED) 36] delete /hadoop 0
version No is not valid : /hadoop #无效的版本号
[zk: localhost:2181(CONNECTED) 37] delete /hadoop 1
[zk: localhost:2181(CONNECTED) 38]
要想删除某个节点及其所有后代节点,可以使用递归删除,命令为 rmr path 。
4.4、查看节点
get path
[zk: localhost:2181(CONNECTED) 1] get /hadoop
123456
cZxid = 0x4
ctime = Thu Dec 12 14:55:53 CST 2019
mZxid = 0x4
mtime = Thu Dec 12 14:55:53 CST 2019
pZxid = 0x4
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 6
numChildren = 0
节点各个属性如下表。其中一个重要的概念是 Zxid(ZooKeeper Transaction Id),ZooKeeper 节点的每一次更改都具有唯一的 Zxid,如果 Zxid1 小于 Zxid2,则Zxid1 的更改发生在 Zxid2 更改之前。
状态属性 | 说明 |
---|---|
cZxid | 数据节点创建时的事务 ID |
ctime | 数据节点创建时的时间 |
mZxid | 数据节点最后一次更新时的事务 ID |
mtime | 数据节点最后一次更新时的时间 |
pZxid | 数据节点的子节点最后一次被修改时的事务 ID |
cversion | 子节点的更改次数 |
dataVersion | 节点数据的更改次数 |
aclVersion | 节点的 ACL 的更改次数 |
ephemeralOwner | 如果节点是临时节点,则表示创建该节点的会话的SessionID;如果节点是持久节点,则该属性值为 0 |
dataLength | 数据内容的长度 |
numChildren | 数据节点当前的子节点个数 |
4.5、查看节点状态
可以使用 stat 命令查看节点状态,它的返回值和 get 命令类似,但不会返回节点数据
[zk: localhost:2181(CONNECTED) 2] stat /hadoop
cZxid = 0x4
ctime = Thu Dec 12 14:55:53 CST 2019
mZxid = 0x4
mtime = Thu Dec 12 14:55:53 CST 2019
pZxid = 0x4
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 6
numChildren = 0
4.6、查看节点列表
查看节点列表有 ls path 和 ls2 path 两个命令,后者是前者的增强,不仅可以查看指定路径下的所有节点,还可以查看当前节点的信息
[zk: localhost:2181(CONNECTED) 0] ls /
[cluster, controller_epoch, brokers, storm, zookeeper, admin, ...]
[zk: localhost:2181(CONNECTED) 1] ls2 /
[cluster, controller_epoch, brokers, storm, zookeeper, admin, ....]
cZxid = 0x0
ctime = Thu Jan 01 08:00:00 CST 1970
mZxid = 0x0
mtime = Thu Jan 01 08:00:00 CST 1970
pZxid = 0x130
cversion = 19
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 0
numChildren = 11
4.7、监听器get path [watch]
使用 get path [watch] 注册的监听器能够在节点内容发生改变的时候,向客户端发出通知。需要注意的是 zookeeper 的触发器是一次性的 (One-time trigger),即触发一次后就会立即失效。
[zk: localhost:2181(CONNECTED) 4] get /hadoop watch
[zk: localhost:2181(CONNECTED) 5] set /hadoop 45678
WATCHER::
WatchedEvent state:SyncConnected type:NodeDataChanged path:/hadoop #节点值改变
4.8、监听器stat path [watch]
使用 stat path [watch] 注册的监听器能够在节点状态发生改变的时候,向客户端发出通知
[zk: localhost:2181(CONNECTED) 7] stat /hadoop watch
[zk: localhost:2181(CONNECTED) 8] set /hadoop 112233
WATCHER::
WatchedEvent state:SyncConnected type:NodeDataChanged path:/hadoop #节点值改变
4.9、监听器ls\ls2 path [watch]
使用 ls path [watch] 或 ls2 path [watch] 注册的监听器能够监听该节点下
所有子节点的增加和删除操作。
[zk: localhost:2181(CONNECTED) 9] ls /hadoop watch
[]
[zk: localhost:2181(CONNECTED) 10] create /hadoop/yarn "aaa"
WATCHER::
WatchedEvent state:SyncConnected type:NodeChildrenChanged path:/hadoop
4.10、Zookeeper 服务端常用命令
#启动 ZooKeeper 服务:
./zkServer.sh start#查看 ZooKeeper 服务状态:
./zkServer.sh status#停止 ZooKeeper 服务:
./zkServer.sh stop #重启 ZooKeeper 服务:
./zkServer.sh restart
4.11、Zookeeper 客户端常用命令
#连接ZooKeeper服务端
./zkCli.sh –server ip:port#断开连接
quit#查看命令帮助
help#显示指定目录下节点
ls 目录
五、zookeeper的Acl权限控制
5.1、概述
zookeeper 类似文件系统,client 可以创建节点、更新节点、删除节点,那么如何做到节点的权限的控制呢?zookeeper的access control list 访问控制列表可以做到这一点。
acl 权限控制,使用scheme:id:permission 来标识,主要涵盖 3 个方面:
- 权限模式(scheme):授权的策略
- 授权对象(id):授权的对象
- 权限(permission):授予的权限
其特性如下:
- zooKeeper的权限控制是基于每个znode节点的,需要对每个节点设置权限
- 每个znode支持设置多种权限控制方案和多个权限
- 子节点不会继承父节点的权限,客户端无权访问某节点,但可能可以访问它的子节点
例如:
setAcl /test2 ip:192.168.60.130:crwda // 将节点权限设置为Ip:192.168.60.130的客户端可以对节点进行增、删、改、查、管理权限
5.2、权限模式
采用何种方式授权
方案 | 描述 |
---|---|
world | 只有一个用户:anyone,代表登录zokeeper所有人(默认) |
ip | 对客户端使用IP地址认证 |
auth | 使用已添加认证的用户认证 |
digest | 使用“用户名:密码”方式认证 |
5.3、授权的对象
给谁授予权限
授权对象ID是指,权限赋予的实体,例如:IP 地址或用户。
5.4、授予的权限
授予什么权限
create、delete、read、writer、admin也就是 增、删、改、查、管理权限,这5种权限简写为cdrwa,注意:这5种权限中,delete是指对子节点的删除权限,其它4种权限指对自身节点的操作权限
权限 | ACL简写 | 描述 |
---|---|---|
create | c | 可以创建子节点 |
delete | d | 可以删除子节点(仅下一级节点) |
read | r | 可以读取节点数据及显示子节点列表 |
write | w | 可以设置节点数据 |
admin | a | 可以设置节点访问控制列表权限 |
5.5、授权的相关命令
命令 | 使用方式 | 描述 |
---|---|---|
getAcl | getAcl | 读取ACL权限 |
setAcl | setAcl | 设置ACL权限 |
addauth | addauth | 添加认证用户 |
5.6、案例
- world授权模式:
命令
setAcl <path> world:anyone:<acl>
案例
[zk: localhost:2181(CONNECTED) 1] create /node1 "node1"
Created /node1
[zk: localhost:2181(CONNECTED) 2] getAcl /node1
'world,'anyone #world方式对所有用户进行授权
: cdrwa #增、删、改、查、管理
[zk: localhost:2181(CONNECTED) 3] setAcl /node1 world:anyone:cdrwa
cZxid = 0x2
ctime = Fri Dec 13 22:25:24 CST 2019
mZxid = 0x2
mtime = Fri Dec 13 22:25:24 CST 2019
pZxid = 0x2
cversion = 0
dataVersion = 0
aclVersion = 1
ephemeralOwner = 0x0
dataLength = 5
numChildren = 0
- IP授权模式:
命令
setAcl <path> ip:<ip>:<acl>
注意:远程登录zookeeper命令:./zkCli.sh -server ip
案例
[zk: localhost:2181(CONNECTED) 18] create /node2 "node2"
Created /node2
[zk: localhost:2181(CONNECTED) 23] setAcl /node2
ip:192.168.60.129:cdrwa
cZxid = 0xe
ctime = Fri Dec 13 22:30:29 CST 2019
mZxid = 0x10
mtime = Fri Dec 13 22:33:36 CST 2019
pZxid = 0xe
cversion = 0
dataVersion = 2
aclVersion = 1
ephemeralOwner = 0x0
dataLength = 20
numChildren = 0
[zk: localhost:2181(CONNECTED) 25] getAcl /node2
'ip,'192.168.60.129
: cdrwa
#使用IP非 192.168.60.129 的机器
[zk: localhost:2181(CONNECTED) 0] get /node2
Authentication is not valid : /node2 #没有权限
- Auth授权模式:
命令
addauth digest <user>:<password> #添加认证用户
setAcl <path> auth:<user>:<acl>
案例
[zk: localhost:2181(CONNECTED) 2] create /node3 "node3"
Created /node3
#添加认证用户
[zk: localhost:2181(CONNECTED) 4] addauth digest angyan:123456
[zk: localhost:2181(CONNECTED) 1] setAcl /node3 auth:angyan:cdrwa
cZxid = 0x15
ctime = Fri Dec 13 22:41:04 CST 2019
mZxid = 0x15
mtime = Fri Dec 13 22:41:04 CST 2019
pZxid = 0x15
cversion = 0
dataVersion = 0
aclVersion = 1
ephemeralOwner = 0x0
dataLength = 5
numChildren = 0
[zk: localhost:2181(CONNECTED) 0] getAcl /node3
'digest,'angyan:673OfZhUE8JEFMcu0l64qI8e5ek=
: cdrwa
#添加认证用户后可以访问
[zk: localhost:2181(CONNECTED) 3] get /node3
node3
cZxid = 0x15
ctime = Fri Dec 13 22:41:04 CST 2019
mZxid = 0x15
mtime = Fri Dec 13 22:41:04 CST 2019
pZxid = 0x15
cversion = 0
dataVersion = 0
aclVersion = 1
ephemeralOwner = 0x0
dataLength = 5
numChildren = 0
- Digest授权模式:
命令
setAcl <path> digest:<user>:<password>:<acl>
这里的密码是经过SHA1及BASE64处理的密文,在SHELL中可以通过以下命令计算:
echo -n <user>:<password> | openssl dgst -binary -sha1 | openssl base64
先来计算一个密文
echo -n angyan:123456 | openssl dgst -binary -sha1 | openssl base64
案例
[zk: localhost:2181(CONNECTED) 4] create /node4 "node4"
Created /node4
#使用是上面算好的密文密码添加权限:
[zk: localhost:2181(CONNECTED) 5] setAcl /node4
digest:angyan:qlzQzCLKhBROghkooLvb+Mlwv4A=:cdrwa
cZxid = 0x1c
ctime = Fri Dec 13 22:52:21 CST 2019
mZxid = 0x1c
mtime = Fri Dec 13 22:52:21 CST 2019
pZxid = 0x1c
cversion = 0
dataVersion = 0
aclVersion = 1
ephemeralOwner = 0x0
dataLength = 5
numChildren = 0
[zk: localhost:2181(CONNECTED) 6] getAcl /node4
'digest,'angyan:qlzQzCLKhBROghkooLvb+Mlwv4A=
: cdrwa
[zk: localhost:2181(CONNECTED) 3] get /node4
Authentication is not valid : /node4 #没有权限
[zk: localhost:2181(CONNECTED) 4] addauth digest angyan:123456 #添加
认证用户
[zk: localhost:2181(CONNECTED) 5] get /node4
1 #成功读取数据
cZxid = 0x1c
ctime = Fri Dec 13 22:52:21 CST 2019
mZxid = 0x1c
mtime = Fri Dec 13 22:52:21 CST 2019
pZxid = 0x1c
cversion = 0
dataVersion = 0
aclVersion = 1
ephemeralOwner = 0x0
dataLength = 5
numChildren = 0
- 多种模式授权:
同一个节点可以同时使用多种模式授权
案例
[zk: localhost:2181(CONNECTED) 0] create /node5 "node5"
Created /node5
[zk: localhost:2181(CONNECTED) 1] addauth digest angyan:123456 #添加认
证用户
[zk: localhost:2181(CONNECTED) 2] setAcl /node5
ip:192.168.60.129:cdra,auth:angyan:cdrwa,digest:angyan:qlzQzCLKhBROgh
kooLvb+Mlwv4A=:cdrwa
5.7、acl 超级管理员
zookeeper的权限管理模式有一种叫做super,该模式提供一个超管可以方便的访问任何权限的节点
假设这个超管是:super:admin,需要先为超管生成密码的密文
echo -n super:admin | openssl dgst -binary -sha1 | openssl base64
那么打开zookeeper目录下的/bin/zkServer.sh服务器脚本文件,找到如下一行:
nohup $JAVA "-Dzookeeper.log.dir=${ZOO_LOG_DIR}" "-Dzookeeper.root.logger=${ZOO_LOG4J_PROP}"
这就是脚本中启动zookeeper的命令,默认只有以上两个配置项,我们需要加一个超管的配置项
"-Dzookeeper.DigestAuthenticationProvider.superDigest=super:xQJmxLMiHGwaqBvst5y6rkB6HQs="
那么修改以后这条完整命令变成了
nohup $JAVA "-Dzookeeper.log.dir=${ZOO_LOG_DIR}" "-Dzookeeper.root.logger=${ZOO_LOG4J_PROP}" "-Dzookeeper.DigestAuthenticationProvider.superDigest=super:xQJmxLMiHGwaqBvst5y6rkB6HQs="\-cp "$CLASSPATH" $JVMFLAGS $ZOOMAIN "$ZOOCFG" > "$_ZOO_DAEMON_OUT" 2>&1 < /dev/null &
之后启动zookeeper,输入如下命令添加权限
addauth digest super:admin #添加认证用户
六、zookeeper的javaApi
znode是zooKeeper集合的核心组件,zookeeper API提供了一小组方法使用zookeeper集合来操纵znode的所有细节。
客户端应该遵循以步骤,与zookeeper服务器进行清晰和干净的交互。
- 连接到zookeeper服务器。zookeeper服务器为客户端分配会话ID。
- 定期向服务器发送心跳。否则,zookeeper服务器将过期会话ID,客户端需要重新连接。
- 只要会话ID处于活动状态,就可以获取/设置znode。
- 所有任务完成后,断开与zookeeper服务器的连接。如果客户端长时间不活动,则zookeeper服务器将自动断开客户端。
6.1、连接到ZooKeeper
ZooKeeper(String connectionString, int sessionTimeout, Watcher watcher)
- connectionString : zookeeper主机
- sessionTimeout : 会话超时(以毫秒为单位)
- watcher : 实现“监视器”对象。zookeeper集合通过监视器对象返回连接状态。
案例:
public class ZookeeperConnection {public static void main(String[] args) {try {// 计数器对象CountDownLatch countDownLatch=new CountDownLatch(1);// arg1:服务器的ip和端口// arg2:客户端与服务器之间的会话超时时间 以毫秒为单位的// arg3:监视器对象ZooKeeper zooKeeper=new ZooKeeper("192.168.60.130:2181",5000, new Watcher() {@Overridepublic void process(WatchedEvent event) {if(event.getState()==Event.KeeperState.SyncConnected){System.out.println("连接创建成功!");countDownLatch.countDown();}}});// 主线程阻塞等待连接对象的创建成功countDownLatch.await();// 会话编号System.out.println(zooKeeper.getSessionId());zooKeeper.close();} catch (Exception ex) {ex.printStackTrace();}}
}
6.2、新增节点
// 同步方式
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 /node1/node11
- data : 要存储在指定znode路径中的数据
- acl : 要创建的节点的访问控制列表。zookeeper API提供了一个静态接口
- ZooDefs.Ids 来获取一些基本的acl列表。例如,ZooDefs.Ids.OPEN_ACL_UNSAFE
返回打开znode的acl列表。
- ZooDefs.Ids 来获取一些基本的acl列表。例如,ZooDefs.Ids.OPEN_ACL_UNSAFE
- createMode : 节点的类型,这是一个枚举。
- callBack:异步回调接口
- ctx:传递上下文参数
案例:
在这里插入代码片
6.3、更新节点
// 同步方式
setData(String path, byte[] data, int version)
// 异步方式
setData(String path, byte[] data, int version,AsyncCallback.StatCallback callBack, Object ctx)
- path: znode路径
- data :要存储在指定znode路径中的数据。
- version: znode的当前版本。每当数据更改时,ZooKeeper会更新znode的版本
号。 - callBack:异步回调接口
- ctx:传递上下文参数
6.4、删除节点
// 同步方式
delete(String path, int version)
// 异步方式
delete(String path, int version, AsyncCallback.VoidCallback callBack,Object ctx)
- path :znode路径。
- version : znode的当前版本
- callBack:异步回调接口
- ctx:传递上下文参数
6.5、查看节点
// 同步方式
getData(String path, boolean b, Stat stat)
// 异步方式
getData(String path, boolean b,AsyncCallback.DataCallback callBack,Object ctx)
- path : znode路径。
- b :是否使用连接对象中注册的监视器。
- stat : 返回znode的元数据。
- callBack :异步回调接口
- ctx :传递上下文参数
6.6、查看子节点
// 同步方式
getChildren(String path, boolean b)
// 异步方式
getChildren(String path, boolean b,AsyncCallback.ChildrenCallback callBack,Object ctx)
- path : Znode路径。
- b : 是否使用连接对象中注册的监视器。
- callBack : 异步回调接口。
- ctx :传递上下文参数
6.7、检查节点是否存在
// 同步方法
exists(String path, boolean b)
// 异步方法
exists(String path, boolean b,AsyncCallback.StatCallback callBack,Object ctx)
- path :znode路径。
- b : 是否使用连接对象中注册的监视器。
- callBack : 异步回调接口。
- ctx :传递上下文参数
相关文章:

zookeeper --- 基础篇
一、zookeeper简介 1.1、什么是zookeeper zookeeper官网:https://zookeeper.apache.org/ 大数据生态系统里的很多组件的命名都是某种动物或者昆虫,他是用来管 Hadoop(大象)、Hive(蜜蜂)、Pig(小 猪)的管理员。顾名思义就是管理…...

Golang map 常用方法
文章目录 前言按key排序按value排序统计字符串中元素重复出现次数并将结果排序返回 前言 由于map是无序的,所以排序成 slice 返回,且都使用泛,代码只是示例,省略了错误判断 按key排序 package mainimport "fmt"func example[T c…...

用于视觉跟踪的在线特征选择研究(Matlab代码实现)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...

Docker基本使用
查看本地镜像 查看本地:docker imagesPull镜像:docker pull nginx:latest登录镜像:docker login hub.docker.com -u **** -p ****制作镜像:docker build -t xxxx:v1push:docker push xxx:v1删除镜像:docker rmi #imag…...

PHP生成随机数
要在 PHP 中生成随机密码,可以使用 rand() 函数和字符串操作函数。以下是一个示例代码来生成包含字母、数字和特殊字符的随机密码 function generateRandomPassword($length 8) {// 定义包含字母、数字和特殊字符的字符集$characters abcdefghijklmnopqrstuvwxyz…...

MongoDB:Unrecognized option: storage
MongoDB一直显示 Unrecognized option: storage try ‘mongod --help’ for more information 意思是我们配置的config文件出了问题。 说明:MongoDB采用的是YAML格式,所以我们只需要稍微改改就好。 在storage前面:没有空格 下面两行最前面…...

Java基础九 - 异常
1. throw 和 throws 1. throw是在代码运行过程中引起一个异常 2. throws是将异常声明但是不处理,而是将异常往上传,谁调用我就交给谁处理 2. final、finally、finalize 1. final是修饰符,用于修饰变量、方法、类修饰变量,最开始…...

[国产MCU]-BL602开发实例-UART数据发送与接收
UART数据发送与接收 文章目录 UART数据发送与接收1、BL602的UART介绍2、UART相关驱动API介绍3、UART使用示例3.1 轮询方式数据接收与发送3.2 中断方式数据接收与发送3.3 DMA方式接收与发送数据通用异步收发传输器(Universal Asynchronous Receiver/Transmitter,通常称为UART)…...

mac安装open3d时候出现错误
在测试open3d是否正常顺利安装时,出现了如下错误: python -c "import open3d as o3d; print(o3d.__version__)" Traceback (most recent call last):File "<string>", line 1, in <module>File "/Users/huangzhe/…...

打造本地户外装备小程序商城教程大揭秘
在如今的移动互联网时代,小程序已经成为了各行各业的发展利器。尤其对于户外用具行业来说,一个专属的小程序商城将能够极大地提升企业的品牌形象和销售业绩。下面就来介绍一下快速上手制作户外用具小程序的攻略吧。 首先,登录乔拓云平台进入商…...

在外SSH远程连接Ubuntu系统
在外SSH远程连接Ubuntu系统【无公网IP】 文章目录 在外SSH远程连接Ubuntu系统【无公网IP】前言1. 在Ubuntu系统下安装cpolar软件2. 完成安装后打开cpolar客户端web—UI界面3. 创建隧道取得连接Ubuntu系统公网地址4. 打开Windows的命令界面并输入命令 前言 随着科技和经济的发展…...

GOTS标准速递---7.0 版将于2024年3月1日起全面生效
【GOTS标准速递---7.0 版将于2024年3月1日起全面生效】 全球有机纺织品标准很高兴地宣布发布GOTS 7.0 版,该版本扩大了环境和社会标准的范围,同时保持了适用于工业生产并适用于各种产品的标准。在为期一年的定期修订过程中,在有机生产、纺织品…...

Ansible的安装和配置
安装和配置 Ansible 安装所需的软件包 创建名为 /home/greg/ansible/inventory 的静态清单文件,以满足以下要求: 172.25.250.9 是 dev 主机组的成员 172.25.250.10 是 test 主机组的成员 172.25.250.11 和 172.25.250.12 是 prod 主机组的成员 172.2…...

口-肠-脑轴与精神健康的关系
谷禾健康 在个体中,每个微生物栖息地都表现出独特的微生物种群模式。迄今为止,关于微生物组相关疾病的研究主要集中在器官特异性微生物组上。然而,器官间的微生物网络正逐渐成为生理功能和病理过程中的重要调节因子和治疗机会。 在正常情况下…...

Dubbo是干嘛的,Dubbo原理和机制,Dubbo的核心组件
目录 一、介绍1、Dubbo是什么2、为什么需要Dubbo3、Dubbo的特性 二、 Dubbo的核心概念1、暴露和引用(Export and Refer)2、服务提供者和服务消费者3、注册中心4、负载均衡5、集群容错 三、Dubbo的架构1、服务提供者和服务消费者之间的通信流程2、Dubbo的…...

自动zksync刷账户交互(附代码)
自动化任务的 Python 代码。它使用 Selenium 库来控制浏览器。 #解锁小狐狸 task.unlock_metamask(ads) #zk主网连接钱包,初始化 #ZK主网任务1:转账 print(选择ZK主网任务1:转账) task.zk_task1(ads,address) #…...

荐读 | 《揭秘云计算与大数据》
当我们回顾过去几十年的科技进步时,云计算和大数据在现代科技发展史上无疑具有里程碑式的意义,它们不仅改变了我们的生活方式,而且对各行各业产生了深远的影响。 在这个数字化时代,云计算和大数据技术已经成为推动全球发展的关键…...

RISC-V基础之内存分布与映射
内存映射是指将地址空间划分为不同的部分或段,每个段有不同的用途和属性。这段话介绍了五个段:文本段、全局数据段、动态数据段、异常处理器段和操作系统(OS)段。下面是对每个段的简要说明: 文本段:存放程序…...

【Unity3D应用案例系列】Unity3D中实现文字转语音的工具开发
推荐阅读 CSDN主页GitHub开源地址Unity3D插件分享简书地址我的个人博客 大家好,我是佛系工程师☆恬静的小魔龙☆,不定时更新Unity开发技巧,觉得有用记得一键三连哦。 一、前言 在开发中,会遇到将文字转语音输出的需求࿰…...

STM32入门——定时器
内容为江科大STM32标准库学习记录 TIM简介 TIM(Timer)定时器定时器可以对输入的时钟进行计数,并在计数值达到设定值时触发中断16位计数器、预分频器、自动重装寄存器的时基单元,在72MHz计数时钟下可以实现最大59.65s的定时&…...

企业工商信息:知识产权出质
一、出质是什么?质权是什么? 出质,作为一种物权行为,是指将个人或企业所拥有的财产权益移交给他人作为抵押,以获得资金支持。这一概念在商业活动中扮演着重要的角色,为企业创造了融资渠道。特别是在知识密…...

batch_softmax_loss
每个用户抽取一定数量的困难负样本,然后ssm def batch_softmax_loss_neg(self, user_idx, rec_user_emb, pos_idx, item_emb):user_emb rec_user_emb[user_idx]product_scores torch.matmul(F.normalize(user_emb, dim1), F.normalize(item_emb, dim1).transpose(…...

刘汉清:从生活到画布,宠物成为灵感源泉
出生于中国镇江的艺术家刘汉清,其作品展现出他对日常生活的深入洞察力,以及对美的独特理解。他的作品通常没有视觉参考,而是通过对他周围环境的理解,尤其是他的宠物,来进行创作。 在刘汉清的创作过程中,他…...

【LeetCode】240.搜索二维矩阵Ⅱ
题目 编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性: 每行的元素从左到右升序排列。每列的元素从上到下升序排列。 示例 1: 输入:matrix [[1,4,7,11,15],[2,5,8,12,19],[3,6,9,16,22],[10,13,…...

SED正则表达式中[方括号]的特殊处理
今天被这个方括号懵晕了,特此记录 例如: 去除输入字符串“1[2.3]4[ab,c]”中的所有方括号和逗号: $ echo "1[2.3]4[ab,c]"|sed -e "s/[,\]\[]//g" 1[2.3]4[ab,c] It doesnt work! 原因:Regular Expressi…...

Android 音频开发
在Android平台上进行音频开发,您需要掌握以下关键知识点: Android平台基础知识:熟悉Android操作系统的基本架构、组件和应用开发的基本概念。 音频API:了解Android提供的音频相关API,主要包括android.media.AudioReco…...

Java8新特性,Lambda,Stream流
Java8新特性,Lambda,Stream流 Java8版本在2014年3月18日发布,为Java语言添加了很多重要的新特性。新特性包括:Lambda表达式、方法引用、默认方法、新的时间日期API、Stream API、Optional类等等。这些新特性大大增强了Java语言的表达能力,使…...

模型训练之train.py代码解析
题目 作者:安静到无声 个人主页 from __future__ import absolute_import from __future__ import division from __future__ import print_function这段代码使用了Python 2.x的__future__模块来导入Python 3.x的一些特性。在Python 2.x中,使用print语句来输出内容,而在Py…...

linux 复习
vim 使用 一般模式 、 命令模式、编辑模式 esc 进入一般模式 i 进入编辑模式 shift: 进入命令模式 yy p 复制粘贴 5yy 复制当前开始的5行 dd 删除 5dd 删除当前开始的5行 u撤销操作 ctrlr 恢复 shiftg 滚动最底部 gg 滚动最顶 输入数字 然后shiftg 跳转到指定行 用户操作…...

C语言刷题------(2)
C语言刷题——————(2) 刷题网站:题库 - 蓝桥云课 (lanqiao.cn) First Question:时间显示 题目描述 小蓝要和朋友合作开发一个时间显示的网站。 在服务器上,朋友已经获取了当前的时间,用一个整数表…...