1.什么是zookeeper?

zookeeper是一个开源的分布式协调服务,由雅虎创建的,基于google chubby.是一个分布式数据一致性的解决方案

2.特性

顺序一致性:在一个客户端发起的事务请求(写请求),会严格按照请求顺序在zk中执行。
原子性:所有的事务请求在集群中的所有节点的处理结果是一致的,要么都成功,要么都失败。
可靠性:一旦服务器成功的处理了某个事务请求,并且对客户端做了响应,那么这个数据一定会存储在整个集群中,并保留下来。
实时性:一旦事务被成功应用,所有的客户端都会查到相应的数据(近实时)

3.数据模型

zk的数据节点类似于文件系统,是由数据节点组成的树形结构,每个节点都称为一个znode,可以存储数据以及节点的状态信息.znode是zk中的最小数据单元。
节点特性:
持久化节点(PERSISTENT):持久化节点一旦创建,就会一直存储在zk系统中,直到主动删除为止
持久化顺序节点(PERSISTENT_SEQUENTIAL):在创建顺序节点时,会在节点的名字后面加上一个序号。在同一个目录的顺序节点,会共同维护一个顺序,序号依次递增,序号范围[0,Integer.Max]
临时节点(EPHEMERAL):临时节点的生命周期和客户端的会话保持一致,当会话结束,节点自动被清理。临时节点下不能创建子节点
临时顺序节点(EPHEMERAL_SEQUENTIAL):比临时节点多了一个顺序性.

zkCli命令

create -s -e /path value acl 		-s顺序节点 -e 临时节点
delete /path [version] 删除节点 (有子节点不能删除)
rmr path 可以删除当前节点及子节点
get /path 获取节点信息
set /path data [version] 修改节点的值	

ls /path 显示子节点
ls2 /path 显示版本信息及子节点

stat /path  [watch]显示节点的版本信息
例如 stat /path true显示节点的版本信息

getAcl /path 获取节点权限
setAcl path acl 修改节点权限
addauth scheme auth 添加权限

watch

zk提供了分布式数据的发布和订阅功能,zk服务端允许客户端注册一个监听,当服务端数据变化时,服务器会生成一个事件通知给客户端,zk的监听是一次性的,既当触发一次通知后,当前watch就会失效,需要重新注册监听

ACL节点权限控制

zk为节点提供权限控制功能,以提高节点数据的安全性,避免误操作导致系统出现安全事故。
节点的权限类型
create、delete、read、write、admin既cdrwa 创建、删除、读、写、管理5种权限

以下信息摘自官网
CREATE: you can create a child node 可以创建子节点
DELETE: you can delete a child node 删除子节点
READ: you can get data from a node and list its children. 可以获取节点数据并查看子节点
WRITE: you can set data for a node 修改节点数据
ADMIN: you can set permissions 为节点设置权限

zk权限的方案schema
world:anyone 相当于没有权限,任何人都能访问(默认级别)
auth 不需要id控制,任何通过认证的用户都能访问
digest:username:password 通过用户名密码控制权限
ip:host 通过ip地址控制权限

world has a single id, anyone, that represents anyone.
auth doesn't use any id, represents any authenticated user.
digest uses a username:password string to generate MD5 hash which is then used as an ACL ID identity. Authentication is done by sending the username:password in clear text. When used in the ACL the expression will be the username:base64 encoded SHA1 password digest.
ip uses the client host IP as an ACL ID identity. The ACL expression is of the form addr/bits where the most significant bits of addr are matched against the most significant bits of the client host IP.

节点状态信息

get /node
aaaba  节点的数据
cZxid = 0x47   节点创建id(创建后不会改变)
ctime = Sat Jan 26 19:29:08 CST 2019 创建时间 (创建后不会改变)
mZxid = 0x52  节点修改的id(节点本身数据修改时改变)
mtime = Sat Jan 26 20:02:38 CST 2019 最后修改时间(节点本身数据修改时改变)
pZxid = 0x4e 子节点id (子节点的创建、删除改变)
cversion = 6 子节点版本 (子节点的创建、删除改变)
dataVersion = 4 数据版本  (节点本身数据修改时改变)
aclVersion = 0 acl版本
ephemeralOwner = 0x0 如果是临时节点存储会话id,非临时节点为0
dataLength = 5 数据长度
numChildren = 6 子节点数量

以下为测试数据

初始化

修改数据

创建子节点

修改子节点数据

创建孙子节点

创建第二个子节点

删除第二个子节点

cZxid = 0x54

cZxid = 0x54

cZxid = 0x54

cZxid = 0x54

cZxid = 0x54

cZxid = 0x54

cZxid = 0x54

ctime = Sat Jan 26 21:16:48 CST 2019

ctime = Sat Jan 26 21:16:48 CST 2019

ctime = Sat Jan 26 21:16:48 CST 2019

ctime = Sat Jan 26 21:16:48 CST 2019

ctime = Sat Jan 26 21:16:48 CST 2019

ctime = Sat Jan 26 21:16:48 CST 2019

ctime = Sat Jan 26 21:16:48 CST 2019

mZxid = 0x54

mZxid = 0x57

mZxid = 0x57

mZxid = 0x57

mZxid = 0x57

mZxid = 0x57

mZxid = 0x57

mtime = Sat Jan 26 21:16:48 CST 2019

mtime = Sat Jan 26 21:18:27 CST 2019

mtime = Sat Jan 26 21:18:27 CST 2019

mtime = Sat Jan 26 21:18:27 CST 2019

mtime = Sat Jan 26 21:18:27 CST 2019

mtime = Sat Jan 26 21:18:27 CST 2019

mtime = Sat Jan 26 21:18:27 CST 2019

pZxid = 0x54

pZxid = 0x54

pZxid = 0x58

pZxid = 0x58

pZxid = 0x58

pZxid = 0x5b

pZxid = 0x5c

cversion = 0

cversion = 0

cversion = 1

cversion = 1

cversion = 1

cversion = 2

cversion = 3

dataVersion = 0

dataVersion = 1

dataVersion = 1

dataVersion = 1

dataVersion = 1

dataVersion = 1

dataVersion = 1

dataLength = 3

dataLength = 2

dataLength = 2

dataLength = 2

dataLength = 2

dataLength = 2

dataLength = 2

numChildren = 0

numChildren = 0

numChildren = 1

numChildren = 1

numChildren = 1

numChildren = 2

numChildren = 1

集群的角色

leader
1.负责集群事物请求的处理
2.与follower和observer节点同步数据
3.负责发起事务请求的投票
follower节点
1.处理客户端的非事务请求并将事务请求转发到leader节点
2.参与事务请求处理的投票(客户端的一个事务请求,需要集群中的半数以上的节点投票通过后,才能通知leader commit;leader会发起一个提案,要求follower投票)
3.参与leader选举的投票
observer
1.将事务请求转发至leader节点
2.不参与事务请求的投票及leader选举的投票
observer的目的是为了扩展系统,提高读取速度。

zk的应用场景

1.统一配置管理

实现思路:zk采用push和pull相结合的方式,配置管理端push配置到zk服务端,应用节点在zk中注册自己关心节点的监听,当数据修改时,服务端就会向客户端推送watch事件通知,client收到通知后主动去zk pull更新的数据,并存储在本地,
满足以下条件时,适合使用统一配置中心
1.数据量较小
2.配置需要动态修改
3.集群中的各个机器共享配置

2.分布式锁

所有的服务节点尝试去zk创建一个相同的锁节点(临时节点),同一时刻只能有一个服务创建成功,创建成功的服务便获取到了锁,创建失败的服务去注册锁节点的监听,当锁节点被删除时,zk会将事件通知给服务节点,服务在获取到事件后,再去创建锁节点,创建成功的服务获取到锁。依次类推

3.master选举

与分布式锁的思路类似,服务尝试去注册相同的选举节点,注册成功的服务为master服务。

4.负载均衡

在zk中创建一个存储服务信息的根节点如/servers,在服务启动后在根节点下创建服务信息的子节点。
当客户端请求到达时,先获取当前服务器的列表信息,根据自定义的负载均衡算法,选取一个服务来处理客户端的请求。

5.ID生成器

在zk的指定节点下创建临时有序节点,根据节点的序号来做ID

6.分布式队列

  1. 通过getChildren获取指定根节点下的所有子节点,子节点就是任务
  2. 确定自己节点在子节点中的顺序
  3. 如果自己不是最小的子节点,那么监控比自己小的上一个子节点,否则处于等待
  4. 接收watcher通知,重复流程