跳至主要內容

zookeeper基本使用

Yaien Blog原创大约 10 分钟微服务zookeeper

zookeeper基本使用

基本概念

通常情况下,单个物理节点很容易达到性能,计算或者容量的瓶颈,所以这个时候就需要多个物理节点来共同完成某项任务,一个分布式系统的本质是分布在不同网络或计算机上的程序组件,彼此通过信息传递来协同工作的系统,而Zookeeper正是一个分布式应用协调框架,在分布式系统架构中有广泛的应用场景。

官方文档解释:zookeeper它是一个分布式协调框架,是ApacheHadoop的一个子项目,它主要是用来解决分布式应用中经常遇到的一些数据管理问题,如:统一命名服务、状态同步服务、集群管理、分布式应用配置项的管理等

核心概念

一个基于内存,用于存储少量数据的数据库。核心概念:文件系统存储结构、监听通知机制

文件系统存储结构

Zookeeper维护一个了类似文件系统的数据结构,每个子目录项都被称作为znode (目录节点),和文件系统类似,我们能够自由的增加、删除znode,在一个znode下增加、删除子znode。

zookeeper有以下几种类型的znode:

1、PERSISTENT­持久化目录节点客户端与zookeeper断开连接后,该节点依旧存在,只要不手动删除该节点,他将永远存在

2、PERSISTENT_SEQUENTIAL­持久化顺序编号目录节点客户端与zookeeper断开连接后,该节点依旧存在,只是Zookeeper给该节点名称进行顺序编号

3、EPHEMERAL­临时目录节点客户端与zookeeper断开连接后,该节点被删除

4、EPHEMERAL_SEQUENTIAL­临时顺序编号目录节点客户端与zookeeper断开连接后,该节点被删除,只是Zookeeper给该节点名称进行顺序编号

5、Container节点(3.5.3版本新增,如果Container节点下面没有子节点,则Container节点在未来会被Zookeeper自动清除,定时任务默认60s检查一次)

6、TTL节点(默认禁用,只能通过系统配置zookeeper.extendedTypesEnabled=true开启,不稳定

监听通知机制

客户端注册监听它关心的任意节点,或者目录节点及递归子目录节点。

1.如果注册的是对某个节点的监听,则当这个节点被删除,或者被修改时,对应的客户端将被通知。

2.如果注册的是对某个目录的监听,则当这个目录有子节点被创建,或者有子节点被删除,对应的客户端将被通知。

3.如果注册的是对某个目录的递归子节点进行监听,则当这个目录下面的任意子节点有目录结构的变化(有子节点被创建,或被删除)或者根节点有数据变化时,对应的客户端将被通知。

注意:所有的通知都是 一次性 的,及无论是对节点还是对目录进行的监听,一旦触发,对应的监听即被移除。递归子节点,监听是对所有子节点的,所以,每个子节点下面的事件同样只会被 触发一次

应用场景

  1. 分布式配置中心
  2. 分布式注册中心
  3. 分布式锁
  4. 分布式队列
  5. 分布式屏障
  6. 集群选举
  7. 发布/订阅

安装

Step1:配置JAVA环境,并检查环境(建议JDK1.8)以上版本

java -version

Step2:下载并解压zookeeper

wget https://mirror.bit.edu.cn/apache/zookeeper/zookeeper‐3.5.8/apache‐zookeeper‐3.5.8‐bin.tar.gz
# 此处若报错  XXXX use ‘--no-check-certificate’. 则在 wget后加入 --no-check-certificate 跳过证书检查

tar ‐zxvf apache‐zookeeper‐3.5.8‐bin.tar.gz

cd apache‐zookeeper‐3.5.8‐bin

Step3:进入/conf目录下重命名zoo_sample.cfg配置文件

cp zoo_sample.cfg zoo.cfg

Step4:修改配置文件,将数据文件路径变更为自定义文件地址

dataDir=/opt/zookeeper/apache-zookeeper-3.5.8-bin/data

Step5:启动

// 可通过 bin/zkServer.sh 查看支持的参数
bin/zkServer.sh start conf/zoo.cfg

Step6:链接服务器

// 如果服务器与客户端在同一台机器,则可以省略ip和端口
bin/zkCli.sh -server 192.168.1.2:2181

如下图即表示zookeeper安装成功

基础命令

help :查看zookeeper所支持的所有命令

ZooKeeper -server host:port cmd args
        addauth scheme auth
        close 
        config [-c] [-w] [-s]
        connect host:port
        create [-s] [-e] [-c] [-t ttl] path [data] [acl]
        delete [-v version] path
        deleteall path
        delquota [-n|-b] path
        get [-s] [-w] path
        getAcl [-s] path
        history 
        listquota path
        ls [-s] [-w] [-R] path
        ls2 path [watch]
        printwatches on|off
        quit 
        reconfig [-s] [-v version] [[-file path] | [-members serverID=host:port1:port2;port3[,...]*]] | [-add serverId=host:port1:port2;port3[,...]]* [-remove serverId[,...]*]
        redo cmdno
        removewatches path [-c|-d|-a] [-l]
        rmr path
        set [-s] [-v version] path data
        setAcl [-s] [-v version] [-R] path acl
        setquota -n|-b val path
        stat [-w] path
        sync path

注意:中括号为可选选项,否则为必填

create :创建新节点

create [-s] [-e] [-c] [-t ttl] path [data] [acl]

# -s:顺序结点
# -e:临时结点
# -c:容器结点
# -t:给结点添加过期时间,默认禁用

create /test-node some-data #没有添加任何参数,默认创建的是持久化结点

# 注意:
# 1.由于zookeeper是一结点组织数据的,没有相对路径,所以所有结点都是以 / 开头
# 2.临时结点下不允许创建子节点
# 3.容器结点当所有子节点都被删除时,下一次轮训会将容器结点清除

get :查看结点

get /test-node

set :修改结点

set /test-node update-data

stat :查看结点状态

stat /test-node

# 展示如下信息
[zk: localhost:2181(CONNECTED) 4] stat /test-node 
// 创建znode的事务ID
cZxid = 0x9
// 创建时间
ctime = Fri Jan 28 12:11:58 CST 2022
// 最后修改znode的事务ID
mZxid = 0x9
// 最近修改时间
mtime = Fri Jan 28 12:11:58 CST 2022
// 最后添加或删除子节点的事务ID(子结点列表发生变化才会发生变化)
pZxid = 0x9
// znode的子节点结果集版本(子节点的变更会影响版本)
cversion = 0
// 数据的版本,当进行set时可以带上此版本号,若set之间版本号已经变更则set失败
dataVersion = 0
aclVersion = 0
// 如果是临时结点,所有者为sessionID,否则此字段为0
ephemeralOwner = 0x0
// 数据字段的长度(字节)
dataLength = 11
numChildren = 0

ls :查看子节点信息

#查看根目录下字节点
ls /

/**  
[zk: localhost:2181(CONNECTED) 5] ls /
[test, test-node, zookeeper]
*/
  
#查看根目录下所有节点
ls -R /
/**
[zk: localhost:2181(CONNECTED) 6] ls -R /
/
/test
/test-node
/zookeeper
/test/sub0
/zookeeper/config
/zookeeper/quota
*/

事件监听机制

针对结点的监听,一定会触发事件,并且该事件立即被移除,所以事件监听是一次性的。

推送的信息不会将变更的数据一并推送,仅仅通知客户端有数据变更,变更的数据需要自己去获取。

// 注册监听的同时获取数据
get -w /path 

// 注册监听的同时获取元数据信息
stat -w /path

# 效果展示

// 为 /test 结点注册监听
[zk: localhost:2181(CONNECTED) 30] get -w /test
xxx

//修改 /test 结点数据
[zk: localhost:2181(CONNECTED) 0] set /test xxx

// 服务端推送的变更信息
[zk: localhost:2181(CONNECTED) 31] 
WATCHER::

WatchedEvent state:SyncConnected type:NodeDataChanged path:/test

针对目录的监听,目录的变化会触发事件,且对应的监听也会被移除,后序结点的创建、删除不会再次触发监听事件。

注册目录监听,不会监听结点数据的变更,只会监听当前目录下结点数量的变更

// 为目录注册监听事件
ls -w /test

# 效果展示
// 注册监听事件
[zk: localhost:2181(CONNECTED) 31] ls -w /test
[]

// 新增子节点
[zk: localhost:2181(CONNECTED) 32] create /test/sub0


// 服务端推送内容
[zk: localhost:2181(CONNECTED) 33] 
WATCHER::

WatchedEvent state:SyncConnected type:NodeChildrenChanged path:/test
Created /test/sub0

Zookeeper的时间类型:

None:连接建立事件

NodeCreate:节点创建

NodeDeleted:节点删除

NodeDataChanged:节点数据变化

NodeChildrenChanged:子节点列表变化

DataWatchRemoved:结点监听被删除

ChildWatchRemoved:子节点监听被删除

ACL权限控制

Zookeeper的ACL权限控制可以控制节点的读写操作,保障数据的安全性,Zookeeper ACL权限设置分为三部分组成:权限模式(Scheme)、授权对象(ID)、权限信息(Permission)。最终组成 "scheme : id : permission" 格式的ACL请求信息。

Scheme(权限模式)

用来设置Zookeeper服务器进行权限验证的方式。

Zookeeper的权限验证方法大体分为一下类型:

  1. **范围验证:**zookeeper可以针对一个IP或者一段IP地址授予某种权限。例如:让一个IP地址为 "192.168.0.10" 的机器对服务器上某个节点具有写入的权限,或者通过 "192.168.0.1/32" 对一段IP地址的机器授。
  2. **口令验证:**即用户名密码方式。在Zookeeper中这种验证方式是 Digest 认证,而Digest这种任何智能方式受限在客户端传送 "username : password" 形式权限表示符后,Zookeeper 服务端会对密码部分使用 SHA-1 和 BASE64 算法进行加密。
  3. **Super:**一种特殊的 Digest 认证,具有Super权限的客户端可以对Zookeeper上的人已数据节点进行任意操作。

ID(授权对象)

授权对象就是我们需要把权限赋予哪一个对象。

对于4中不同的权限模式来说

  1. 采用IP方式,使用的权限对象可以是一个IP地址或一段IP地址;
  2. 采用Digest或Super方式,则对应于一个用户名;
  3. 采用World模式,是授权所有用户;

Permission(权限信息)

权限信息指可以在数据节点上执行的操作种类。

Zookeeper中已经定义好的权限有如下:

数据节点(c : create)创建权限:授予权限的对象可以在数据节点下创建子节点

数据节点(w : wirte)更新权限:授予权限的对象可以更新改数据节点;

数据节点(r : read)读取权限:授予权限的对象可以读取该节点的内容以及子节点的列表信息;

数据节点(d : delete)删除权限:授予权限的对象可以删除该节点下的子节点

数据节点(a : admin)管理员权限:授予权限的对象可以对该节点体进行ACL权限设置;

使用

// 获取某个节点的ACL权限信息
getAcl

// 设置某个节点的ACL权限信息
setAcl

// 输入认证授权信息,相当于注册用户信息; 注册时输入明文密码,zk将以密文形式存储
addauth


# 可以通过系统参数zookeeper.skipACL=yes进行配置,默认是no,可以配置为true,则配置过的ACL将不再进行权限检测

生成授权ID的方式

  1. 使用Zookeeper源码包内的类进行生成
@Test
public void generateSuperDigest() throws NoSuchAlgorithmException {
		String sId = DigestAuthenticationProvider.generateDigest("yaien:test");
		System.out.println(sId);  //yaien:X/NSthOB0fD/OT6iilJ55WJVado=
}
  1. 在XShell生成
echo -n <username>:<password> | openssl dgst -binary -sha1 | openssl base64
// +7K83PhyQ3ijGj0ADmljf0quVwQ=

设置ACL的两种方式

  1. 节点创建的同时设置ACL
// 创建一个zknode节点并赋予 user1 用户读写的权限
create /zknode dddd digest:user1:+7K83PhyQ3ijGj0ADmljf0quVwQ=:rw

// 修改zknode节点的权限
setAcl /zknode digest:user1:+7K83PhyQ3ijGj0ADmljf0quVwQ=:acwrd

添加权限信息后的节点,不能直接访问,否则报错

[zk: localhost:2181(CONNECTED) 3] get /zknode 
// 异常信息
org.apache.zookeeper.KeeperException$NoAuthException: KeeperErrorCode = NoAuth for /zknode

访问前需要添加权限信息

// 添加访问权限信息
addauth digest user1:pass1

// 访问数据
get /zknode


[zk: localhost:2181(CONNECTED) 8] addauth digest user1:pass1
[zk: localhost:2181(CONNECTED) 9] get /zknode 
dddd
[zk: localhost:2181(CONNECTED) 10] 
  1. auth铭文授权
// 注册用户信息,后续可以直接使用铭文授权
addauth digest u100:p100

// 创建节点并赋予权限(这时u100用户授权信息会被zk保存,可以认为当前的授权用户为u100)
create /note-1 node1data auth:u100:p100:cawrd

// 访问数据
get /node-1

注意:创建时授予权限时,节点数据不能为空

上次编辑于:
贡献者: yanggl