1. ZooKeeper的特性

ZooKeeper的特性主要从会话、数据节点,版本,Watcher,ACL权限控制,集群角色这些部分来了解,其中需要重点掌握的数据节点与Watcher

1.1 会话

客户端与服务端的一次会话连接,本质是TCP长连接,通过会话可以进行心跳检测和数据传输

zookeeper怎么分发消息_java

会话(session)是zookepper非常重要的概念,客户端和服务端之间的任何交互操作都与会话有关

会话状态

根据上图,ZooKeeper客户端和服务端成功连接后,就创建了一次会话,ZooKeeper会话在整个运行期间的生命周期中,会在不同的会话状态之间切换,这些状态包括:

CONNECTING、CONNECTED、RECONNECTING、RECONNECTED、CLOSE

一旦客户端开始创建ZooKeeper对象,那么客户端状态就会变成CONNECTING状态,同时客户端开始尝试连接服务端,连接成功后,客户端状态变为CONNECTED,通常情况下,由于断网或其他原因,客户端与服务端之间会出现断开情况,一旦碰到这种情况,ZooKeeper客户端会自动进行重连服务,同时客户端状态再次变成CONNECTING,直到重新连上服务端后,状态又变为CONNECTED,在通常情况下,客户端的状态总是介于CONNECTINGCONNECTED之间。但是,如果出现诸如会话超时、权限检查或是客户端主动退出程序等情况,客户端的状态就会直接变更为CLOSE状态

1.2 数据模型

  ZooKeeper的视图结构和标准的Unix文件系统类似,其中每个节点称为“数据节点”或ZNode,每个ZNode可以存储数据,还可以挂载子节点,因此可以称之为“树”;第二点需要注意的是,每一个znode都必须有值,如果没有值,节点是不能创建成功的

zookeeper怎么分发消息_大数据_02

  • 在ZooKeeper中,ZNode是一个跟Unix文件系统路径相似的节点,可以往这个节点存储或获取数据
  • 通过客户端可对ZNode进行增删改查的操作,还可以注册watcher监控ZNode的变化

1.3 ZooKeeper节点类型

1. Znode有两种类型

  • 短暂(ephemeral)(create -e /app1/test1 “test1” 客户端断开连接zk删除ephemeral类型节点) 
  • 持久(persistent) (create -s /app1/test2 “test2” 客户端断开连接zk不删除persistent类型节点)

  临时节点不能创建子节点

2. Znode有四种形式的目录节点(默认是persistent )

  • PERSISTENT 
  • PERSISTENT_SEQUENTIAL(持久序列/test0000000019 ) 
  • EPHEMERAL 
  • EPHEMERAL_SEQUENTIAL

3. 创建znode时设置顺序标识,znode名称后会附加一个值,顺序号是一个单调递增的计数器,由父节点维护 

zookeeper怎么分发消息_大数据_03

4. 在分布式系统中,顺序号可以被用于为所有的事件进行全局排序,这样客户端可以通过顺序号推断事件的顺序

1.4 ZooKeeper节点状态属性

属性

数据结构

描述

zxid

long

致使ZooKeeper节点状态改变的每一个操作都将使节点接收到一个zxid格式的时间戳

czxid

long

节点被创建的时间对应zxid格式的时间戳

mzxid

long

节点被修改的时间对应zxid格式的时间戳【与子节点无关】

pzxid

long

子节点最近一次创建/修改的时间对应zxid格式的时间戳【和孙子节点无关】

ctime

long

节点被创建的时间

mtime

long

节点最后一次被修改的时间

version

long

节点被修改产生的版本号

cversion

long

子节点被修改产生的版本号

aversion

long

节点的ACL被修改的版本号

emphemeralOwner

long

如果此节点为临时节点,那么它的值为这个节点拥有者的会话ID;否则,它的值为0

dataLength

int

节点数据域的长度

numChildren

int

节点拥有子节点的个数

 

1.5 ACL权限控制机制

ACL机制,表示为scheme:id:permissions,第一个字段表示授权策略,第二个id表示授权对象,permissions表示授予的权限(如只读,读写,管理等)

 1.5.1 scheme:授权策略
  • world:只有一个id叫做anyone,world:anyone对应任何人,在zookeeper中表示所有人都有权限的节点
  • auth:id一般是username:password,代表已经认证通过的用户(可以通过addauth digest user:pwd 来添加授权用户)
  • digest:它对应的id为username:BASE64(SHA1(password)),它需要先通过username:password形式的authentication
  • ip:使用IP地址认证,id一般是客户机的ip地址
1.5.2 id:授权对象
  • world策略的id只能是anyone
  • auth策略的id一般是username:password
  • digest策略的id是username:BASE64(SHA1(password))
  • ip策略的id就是客户端的IP地址
1.5.3 permissions:授予的权限

CREATE【增】、READ【读】、WRITE【写、修改】、DELETE【删】、ADMIN【管理、授权】,简写即crwda

  • CREATE【c】:创建子节点的权限
  • READ【r】:读取节点数据的权限
  • WRITE【w】:修改节点数据的权限
  • DELETE【d】:删除子节点的权限
  • ADMIN【a】:给子节点授权的权限

1.6  Watcher监听机制

  Watcher 监听机制是 Zookeeper 中非常重要的特性,我们基于 zookeeper 上创建的节点,可以对这些节点绑定监听事件,比如可以监听节点数据变更、节点删除、子节点状态变更等事件,通过这个事件机制,可以基于 zookeeper实现分布式锁、集群管理等功能

watcher 特性

  • 当数据发生变化的时候, zookeeper 会产生一个 watcher 事件,并且会发送到客户端。但是客户端只会收到一次通知
  • 如果后续这个节点再次发生变化,那么之前设置 watcher 的客户端不会再次收到消息。watcher 是一次性的操作,可以通过循环监听去达到永久监听效果

如何注册事件机制

  • ZooKeeper 的 Watcher 机制,总的来说可以分为三个过程:客户端注册 Watcher、服务器处理 Watcher 和客户端回调 Watcher客户端
  • 注册 watcher 有 3 种方式,getData、exists、getChildren

 

2. ZooKeeper的常用命令

2.1 服务端

通过bin目录下的zkServer.sh脚本进行服务端的相关操作

  • 启动服务:./zkServer.sh start
  • 服务状态查看:./zkServer.sh status
  • 停止服务
  • 重启服务

  

zookeeper怎么分发消息_java_04

2.2 客户端

连接zookeeper服务:./zkCli.sh -server ip:port,连接成功后,系统会输出ZooKeeper 的相关环境以及配置信息

节点其实就是一个目录、文件

2.2.1 create [-e] [-s] path data [acl]

创建节点

1. 不加参数是创建持久节点

zookeeper怎么分发消息_zookeeper怎么分发消息_05

2. 使用-e参数创建一个临时节点

zookeeper怎么分发消息_数据结构与算法_06

3. 使用-s参数创建一个有序号的节点

zookeeper怎么分发消息_数据结构与算法_07

4. 使用acl参数创建节点时,给节点授予指定权限【crwda】

zookeeper怎么分发消息_数据结构与算法_08

2.2.2 ls path  

使用ls命令查看ZooKeeper的path路径下包含的节点。ls /是查看zookeeper根目录下的所有节点

zookeeper怎么分发消息_客户端_09

 

 

 2.2.3 ls2 path

查看path路径下的所有节点,并且显示出当前节点path的一些状态信息

zookeeper怎么分发消息_zookeeper怎么分发消息_10

 

 

2.2.4 get path [watch]

查看节点内容

zookeeper怎么分发消息_java_11

可以使用watch设置监听,下一次写操作【修改、删除、设置子节点】时触发监听,但是只能生效一次

zookeeper怎么分发消息_大数据_12

2.2.5 set path

修改path节点内容

zookeeper怎么分发消息_大数据_13

2.2.6 delete path

删除path节点

zookeeper怎么分发消息_大数据_14

2.2.7 rmr path

递归删除

path节点如果有子节点使用delete命令就不能删除了,这时就可以使用rmr命令了

zookeeper怎么分发消息_zookeeper怎么分发消息_15

2.2.8 其他一些常用命令

quit  退出客户端

help  帮助命令

2.3 ACL权限控制

ZooKeeper的ACL(Access Control List),分为三个维度:scheme、id、permission。通常表示为:scheme:id:permission

  • schema:代表授权策略。world、auth、digest、ip
  • id:代表用户
  • world对应id:anyone
  • auth对应id:username:password
  • digest对应id:username:BASE64(SHA1(password))
  • ip对应id:客户端ip地址
  • permission:代表权限。CREATE、READ、WRITE、DELETE、ADMIN,简写crwda
2.3.1 getAcl命令

获取指定节点的ACL信息

zookeeper怎么分发消息_客户端_16

2.3.2 setAcl命令

设置指定节点的ACL信息

zookeeper怎么分发消息_大数据_17

 2.3.3 addauth命令

addauth digest username:pwd;

注册会话授权信息

常用授权方式有两种,auth和digest

2.3.3.1 auth

授权前必须使用addauth添加一个用户,否则会报错

zookeeper怎么分发消息_大数据_18

由于/test/children01节点没有d的权限,所以无法删除/test/children01/testa节点

断开客户端重新连接测试

zookeeper怎么分发消息_客户端_19

需要重新新增权限才可以访问

2.3.3.2 digest

auth与digest的区别就是,前者使用明文密码进行登录,后者使用密文密码进行登录

zookeeper怎么分发消息_java_20

 注意:这里如果使用明文,会导致该znode不可访问

这里密文的获取可以使用如下方式:

java -Djava.ext.dirs=/soft/zookeeper/lib -cp /soft/zookeeper/zookeeper-3.4.12.jar org.apache.zookeeper.server.auth.DigestAuthenticationProvider user1:123456

zookeeper怎么分发消息_java_21

 断开客户端重新连接:

zookeeper怎么分发消息_大数据_22

 需要添加用户认证才可以使用

2.3.4 acl命令ip

zookeeper怎么分发消息_java_23

2.3.5 acl设置r权限,无法删除

setAcl权限的时候由于失误,导致节点无法删除

  create /test/node1  enjoy

  setAcl /test  world:anyone:r

  这个时候无论是delete 还是rmr都没有权限删除

  解决方式:启用super权限

   使用DigestAuthenticationProvider.generateDigest("super:admin"); 获得密码

  1. 修改zkServer启动脚本增加

    "-Dzookeeper.DigestAuthenticationProvider.superDigest=super:xQJmxLMiHGwaqBvst5y6rkB6HQs="

  2. 启动客户端用管理员登陆

       addauth digest super:admin

2.4 常用四字命令

ZooKeeper 支持某些特定的四字命令字母与其的交互。用来获取 ZooKeeper 服务的当前状态及相关信息。可通过 telnet 或 nc 向 ZooKeeper 提交相应的命令

echo stat|nc 127.0.0.1 2181

查看哪个节点被选择作为follower或者leader 

echo ruok|nc 127.0.0.1 2181

测试是否启动了该Server,若回复imok表示已经启动

echo conf | nc 127.0.0.1 2181

输出相关服务配置的详细信息

echo reqs | nc 127.0.0.1 2181

列出未经处理的请求

echo wchs | nc 127.0.0.1 2181

列出服务器 watch 的详细信息

echo kill | nc 127.0.0.1 2181

 关掉server