引言
最近公司项目要使用zookeeper作为分布式锁了,所以打算系统的了解一下zookeeper的使用特性、底层源码、leader选举机制、底层ZAB协议,以防项目使用过程中遇到诡异的问题而不知所措。预计分个4至5篇文章写一下,记录过程的同时也可以分享知识。
什么是zookeeper
在以往的工作包括现在的面试中,对zookeeper印象最深的或许就是作为阿里dubbo框架的注册中心(时过境迁,现在已经是apache dubbo了(;´д`)ゞ)。官方对zookeeper的定义是:ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件。
没想到吧,zookeeper使用最多的场景还是大数据领域(●ˇ∀ˇ●)。
zookeeper节点类型
- 持久化目录节点:客户端与zookeeper断开连接后,该节点依旧存在,只要不手动删除该节点,他将永远存在
- 持久化顺序编号目录节点:客户端与zookeeper断开连接后,该节点依旧存在,只是Zookeeper给该节点名称进行顺序编号
- 临时目录节点:zookeeper在一段时间内(超时时间)没有ping通此类型节点,会自动删除此节点,临时节点不能有子节点
- 临时顺序编号目录节点:和临时节点类似,只是在临时节点的基础上,zk对节点进行编号
- 容器节点:容器节点是一个比较特殊的节点,容器节点主要用于装载子节点,当容器节点下面没有子节点,则容器节点在未来会被Zookeeper自动清除,定时任务默认60s 检查一次
zookeeper节点监听机制
zk的可以对它的所有节点进行监听,主要是以下三种监听方式:
- 节点监听:当节点被删除或者修改时,客户端会收到通知
- 目录监听:当目录存在子节点创建或者子节点删除时,客户端会收到通知
- 目录递归子节点监听:当目录任意子节点有目录结构变化或者根节点数据变化时,客户端会收到通知
zookeeper本地部署
既然要了解zk功能,那势必要将zk本地部署了,zk部署比较简单,以下四步即可完成:
- 下载并解压zk文件包,地址为:,解压命令使用:tar -zxvf apache-zookeeper-3.5.8-bin.tar.gz
- 拷贝一份配置文件,以备不时之需(当前如果需要“伪集群”部署也会需要多个配置文件)使用: cp zoo_sample.cfg zoo.cfg
- 修改zoo.cfg的data参数,防止文件存储数据丢失,dataDir=/home/tangshi/apache-zookeeper-3.5.8-bin/data
- 通过zk自带的启动脚本启动即可:bin/zkServer.sh start conf/zoo.cfg,启动完成后使用 :bin/zkCli.sh -server 192.168.1.104:2181 ,连接zkServer就可以对zk进行系列操作了。
zookeeper常用基础命令
1、create [-s] [-e] [-c] [-t ttl] path [data] [acl],中括号为可选项,没有则默认创建持久化节点
- -s: 顺序节点
- -e: 临时节点
- -c: 容器节点
- -t: 可以给节点添加过期时间,默认禁用,需要通过系统参数启用
- acl:节点权限设置
2、get [-s] [-w] path:查看节点的数据
- -w: 添加监听器
3、set [-s] [-v version] path data:修改节点数据
4、delete [-v version] path:删除节点
5、ls [-s] [-w] [-R] path:查看节点
6、stat [-w] path:查看节点状态,效果如下:
stat查看节点状态
- cZxid:创建znode的事务ID(Zxid的值)。
- mZxid:最后修改znode的事务ID。
- pZxid:最后添加或删除子节点的事务ID(子节点列表发生变化才会发生改变)。
- ctime:znode创建时间。
- mtime:znode最近修改时间。
- dataVersion:znode的当前数据版本。
- cversion:znode的子节点结果集版本(一个节点的子节点增加、删除都会影响这个版本)。
- aclVersion:表示对此znode的acl版本。
- ephemeralOwner:znode是临时znode时,表示znode所有者的 session ID。 如果znode不是临时znode,则该字段设置为零。
- dataLength:znode数据字段的长度。
- numChildren:znode的子znode的数量。
zookeeper时间监听机制
zk可以对其节点或者进行监听,在发生对应的事件触发,触发后,对应的注册立刻移除,监控命令如下:
get -w /path // 对节点注册监听
stat -w /path // 对节点注册监听,
ls -w /path //对目录进行监听,当目录结构发生变化时触发
ls -R -w /path //对当前目录以及所有的子节点进行监听
zk事件类型如下:
- None: 连接建立事件
- NodeCreated: 节点创建
- NodeDeleted: 节点删除
- NodeDataChanged:节点数据变化
- NodeChildrenChanged:子节点列表变化
- DataWatchRemoved:节点监听被移除
- ChildWatchRemoved:子节点监听被移除
zk事件被触发效果如下图:
节点数据变化触发节点改变事件
zookeeper权限控制(ACL)
zookeeper可以控制节点的读写操作,来保证zk节点的数据安全性。zk的ACL分为权限模式、权限对象、权限信息三个模块,详细解释如下:
- 权限模式:scheme,分为范围验证和口令验证,范围验证时对一段ip或者一个ip进行赋权,口令模式则是通过用户明和密码验证,通过Digest认证方式验证。
- 权限对象:如果权限模式为范围验证,则授权对象为ip或者ip地址段。权限模式为口令模式时,则对应一个用户名。如果对象为World,则是对所有的用户进行授权
- 权限信息:即数据节点的操作种类,分别为:
- 数据节点(c: create)创建权限,授予权限的对象可以在数据节点下创建子节点;
- 数据节点(w: wirte)更新权限,授予权限的对象可以更新该数据节点;
- 数据节点(r: read)读取权限,授予权限的对象可以读取该节点的内容以及子节点信息;
- 数据节点(d: delete)删除权限,授予权限的对象可以删除该数据节点的子节点;
- 数据节点(a: admin)管理者权限,授予权限的对象可以对该数据节点进行管理 ACL 权限。
设置节点ACL有两种方式,一种时通过create方法,在创建节点的时候赋权,另外一种是通过setAcl方式进行赋权,详细如下:
create /cute-bear xiaomao digest:admin:dyks0yAxrXfvFZ7G5BN0+ZUcGCE=:cdrwa
setAcl /cute-bear digest:admin:dyks0yAxrXfvFZ7G5BN0+ZUcGCE=:cdrwa
设置权限之后,直接使用get方法获取节点数据则报异常:org.apache.zookeeper.KeeperException$NoAuthException: KeeperErrorCode = NoAuth for /encry-node-admin,需要通过:addauth digest admin:admin123 进行登录后,才可正常读取节点数据。另外提一下,zk设置acl还有一种明文方式,登陆后就可以对节点直接使用密文添加授权。当用户忘记节点密码后,可以使用超级管理员模式进行密码修改:
- 启动参数添加 -Dzookeeper.DigestAuthenticationProvider.superDigest=super:<base64encoded(SHA1(密码))
- 使用addauth digest super:密码进行登录,最后使用setAcl修改密码即可
以上就是zookeeper最基本的一些配置功能,下一篇文档会针对zk集群部署以及一些进阶应用进行梳理。