1.zookeeper 简介
ZooKeeper 致力于提供一个高性能、高可用,且具备严格的顺序访问控制能力的分布式协调服务,是雅虎公司创建,是 Google 的 Chubby 一个开源的实现,也是 Hadoop 和 Hbase 的重要组件。
2. 设计目标
- 简单的数据结构:共享的树形结构,类似文件系统,存储于内存;
- 可以构建集群:避免单点故障,3- 5 台机器就可以组成集群,超过半数正常工作就能对外提供服务;
- 顺序访问:对于每个读请求,zk 会分配一个全局唯一的递增编号,利用这个特性可以实现高级协调服务;
- 高性能:基于内存操作,服务于非事务请求,适用于读操作为主的业务场景。3 台 zk 集群能达到 13w QPS;
3. 应用场景
- 数据发布订阅 (以下都是基于数据发布订阅)
- 负载均衡
- 命名服务
- Master 选举
- 集群管理
- 配置管理
- 分布式队列
- 分布式锁
4.zookeeper 基础
linux 下安装 zookeeper:
目录结构:
bin →存放系统脚本
conf → 存放配置文件
contrib → zk 附加功能支持
dist-maven → maven 仓库文件
docs → zk 文档
lib → 依赖的第三方库
recipes → 经典场景样例代码
src → zk 源码
其中 bin 和 conf 是非常重要的两个目录,也是经常用的。
bin 目录:
其中 zkServer 为服务器,启动后默认端口为 2181
zkCli 为命令行客户端
conf 目录:这里就不一一列举了,具体查阅资料
5.ZK 的特性
Zk 的特性会从会话、数据节点,版本,Watcher,ACL 权限控制,集群角色这些部分来了解,其中重点需要掌握的数据节点与 Watcher。
5.1 会话
客户端与服务端的一次会话连接,本质是 TCP 长连接,通过会话可以进行心跳检测和数据传输;
会话(session)是 zookepper 非常重要的概念,客户端和服务端之间的任何交互操作都与会话有关。
会话状态图:
Zk 客户端和服务端成功连接后,就创建了一次会话,ZK 会话在整个运行期间的生命周期中,会在不同的会话状态之间切换,这些状态包括:
CONNECTING、CONNECTED、RECONNECTING、RECONNECTED、CLOSE
- 一旦客户端开始创建 Zookeeper 对象,客户端状态就会变成 CONNECTING 状态。
- 同时客户端开始尝试连接服务端,连接成功后,客户端状态变为 CONNECTED.
通常情况下,由于断网或其他原因,客户端与服务端出现断开情况,Zookeeper 客户端会自动进行重连服务,同时客户端状态再次变成 CONNCTING,直到重连上后,状态又变为 CONNECTED,一般客户端的状态总是介于 CONNECTING 和 CONNECTED 之间。
但是,如果出现诸如会话超时、权限检查或是客户端主动退出程序等情况,客户端的状态就会直接变更为 CLOSE 状态
5.2 ZK 数据模型
ZooKeeper 的视图结构和标准的 Unix 文件系统类似,其中每个节点称为“数据节点”或 ZNode, 每个 znode 可以存储数据,还可以挂载子节点,因此可以称之为“树”.
注意:创建节点的时候必须设置值,不然节点是创建不成功的。
- 在 Zookeeper 中,znode 是一个跟 Unix 文件系统路径相似的节点,可以往这个节点存储或获取数据
- 通过客户端可对 znode 进行增删改查的操作,还可以注册 watcher 监控 znode 的变化。
5.3 ZK 节点类型
节点类型是非常重要的, 是项目实战的基础。
a、Znode 有两种类型:
短暂(ephemeral)(create -e /testlinshi/linshi test1 客户端断开连接 zk 删除 ephemeral 类型节点, 即 linshi 节点)
持久(persistent)(create -p /testlinshi/linshi test2 客户端断开连接 zk 不删除 persistent 类型节点)
b、Znode 有四种形式的目录节点(默认是 persistent, 持久)
PERSISTENT
PERSISTENT_SEQUENTIAL(持久序列 /test0000000019)
EPHEMERAL
EPHEMERAL_SEQUENTIAL
创建 znode 时带 - s 参数即是顺序节点,znode 名称后会附加一个值,顺序号是一个单调递增的计数器,由父节点维护
c、在分布式系统中,顺序号可以被用于为所有的事件进行全局排序,这样客户端可以通过顺序号推断事件的顺序.
5.4 zookeeper 节点状态属性
如图
5.5 ACL 保障数据的安全
举个例子查看 znode 的 ACL 信息
world anyone cdrwa 三个字段为 ACL 信息, 第一个字段表示采用哪一种机制,第二个 id 表示用户,permissions 表示相关权限(如只读,读写,管理等), 即 schemepermissions。
zookeeper 提供了如下几种机制(scheme):
- world: 它下面只有一个 id, 叫 anyone,world:anyone 代表任何人,zookeeper 中对所有人有权限的结点就是属于 world:anyone 的
- auth: 它不需要 id, 只要是通过 authentication 的 user 都有权限(zookeeper 支持通过 kerberos 来进行 authencation, 也支持 username/password 形式的 authentication)
- digest: 它对应的 id 为 username:BASE64(SHA1(password)),它需要先通过 username:password 形式的 authentication
- ip: 它对应的 id 为客户机的 IP 地址,设置的时候可以设置一个 ip 段,比如 ip:192.168.1.0/16,
表示匹配前 16 个 bit 的 IP 段
机制为 auth:
addauth digest username:123456 # 需要先添加一个用户
setAcl /testAcl-auth auth:username:123456:crwa # 然后才可以拿着这个用户去设置权限, 设置 auth 机制
getAcl /testAcl-auth # 密码都是以密文的形式存储的
机制为 digest:
create /testAcl-digest1 123
addauth digest username1:IkghJ5CIcrw6bRa3Zu2aSo2IblQ= # 需要先添加一个用户
setAcl /testAcl-digest1 digest:username1:IkghJ5CIcrw6bRa3Zu2aSo2IblQ=:crwa # 然后才可以拿着这个用户去设置权限, 设置 digest 机制
注意设置 digest 机制的时候密码都是以密文形式的
getAcl /testAcl-digest1 # 密码都是以密文的形式存储的
密文也可以在 linux 下通过命令获取:
shell>
java -Djava.ext.dirs=/soft/zookeeper-3.4.12/lib -cp /soft/zookeeper-3.4.12/zookeeper-3.4.12.jar org.apache.zookeeper.server.auth.DigestAuthenticationProvider username1:123456
username1:123456-> username1: IkghJ5CIcrw6bRa3Zu2aSo2IblQ=
Permission
CREATE、READ、WRITE、DELETE、ADMIN 也就是 增、删、改、查、管理权限,这 5 种权限简写为 crwda(即:每个单词的首字符缩写)
CREATE(c):创建子节点的权限
DELETE(d):删除节点的权限(删除当前节点下的任意节点的权限)
READ(r):读取节点数据的权限
WRITE(w):修改节点数据的权限
ADMIN(a):设置子节点权限的权限
5.6 zookeeper 日志可视化
前面以及讲了两个非常重要的配置一个是 dataDir,存放的快照数据,一个是 dataLogDir,存放的是事务日志文件。
查看快照文件:
查看日志文件则是用另一个类 LogFormatter
java -cp /usr/local/zookeeper-3.4.14/zookeeper-3.4.14.jar:/usr/local/zookeeper-3.4.14/lib/slf4j-api-1.7.25.jar org.apache.zookeeper.server.LogFormatter log.14