ZooKeeper基础整理(一)

概述

  • ZooKeeper是分布式协调服务程序, 可以实现分布式协调& 通知, 命名服务, 负载均衡, 分布式状态同步, 微服务的注册中心, 配置中心等, 同时它也提供缓存服务, 但不同于 Redis, ZooKeeper的键是树形层次结构, 它主要用来存储协调状态以及中心配置等信息, 且每个节点的存放数据上限为1M.

基本特性

  1. 原子性(Atomicity)
  2. 唯一视图(Single System Image), 最终一致性: 无论连接到哪个服务器, 看到的都是同一个视图
  3. 顺序一致性(Sequential Consistency): 同一个客户端的更新请求是按顺序执行的

节点(Znode)

  • Zookeeper的数据模型是树形层次结构, 类似于文件系统, 不同在于任何节点都有自己的命名空间, 且也可以创建子节点, 而文件系统中只有文件节点可以存放数据, 目录节点不行

节点特点

  1. 所有节点都维护着 Metadata(元数据), ACL(Access Control List访问控制列表, 权限控制机制), 时间戳等, 又有文件系统的目录特点可以拥有子节点
  2. 可以存的数据上限为1M
  3. 键的格式是 Unix/Linux路径形式, 开头必须是由/(斜杠)来开头

节点类型

  • Persistent(持久节点): 永久保存, 除非手动删除
  • Ephemeral(临时节点): 与客户端的会话生命周期有关, 当会话失效, 临时节点就会被删除
  • Persistent_Sequential(持久顺序节点): 与 Persistent(持久节点)基本特性相同, 又有顺序属性, 节点名后边会自动追加一个由父节点维护的自增长整型数字.(格式为10位数字, 例0000000001)
  • Ephemeral_Sequential(临时顺序节点): 与 Ephemeral(临时节点)基本特性相同, 又有顺序属性, 节点名后边会自动追加一个由父节点维护的自增长整型数字
  • Container(容器节点): 基本特性与持久节点相同, 但有附加属性, 即删除最后一个子节点(或本身是空容器)时自动将其删除, 适合用于分布式锁
  • TTL Nodes(限时节点): 指定时间内未被修改, 自动将其删除

节点信息


[zk: localhost:2181(CONNECTED) 28] get -s /test-key
tset-Value # 值
cZxid = 0x9 # 事务id
ctime = Sat Aug 01 14:50:50 CST 2020 # 创建时间
mZxid = 0x9 # 被修改的事务id, 即每次修改都会更新 mZxid
mtime = Sat Aug 01 14:50:50 CST 2020 # 修改时间
pZxid = 0x9 # 子节点(不含子子节点)个数变化时会更新 pZxid
cversion = 0 # 子节点(不含子子节点)个数的变化次数
dataVersion = 0 # 数据的变化次数
aclVersion = 0 # 节点权限的变化次数
ephemeralOwner = 0x0 # 持久节点时值为0x0. 临时节点时值为 Sessionid, 貌似 0x1000138bc460001
dataLength = 10 # 数据的字节个数
numChildren = 0 # 子节点(不含子子节点)个数

命令


ZooKeeper -server host:port -client-configuration properties-file cmd args
	addWatch [-m mode] path # optional mode is one of [PERSISTENT, PERSISTENT_RECURSIVE] - default is PERSISTENT_RECURSIVE
	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 [-b batch size]
	delquota [-n|-b] path
	get [-s] [-w] path
	getAcl [-s] path
	getAllChildrenNumber path
	getEphemerals path
	history 
	listquota path
	ls [-s] [-w] [-R] path
	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]
	set [-s] [-v version] path data
	setAcl [-s] [-v version] [-R] path acl
	setquota -n|-b val path
	stat [-w] path
	sync path
	version
 
  • 常用命令

ls / # 查看根节点下的子节点
create /test-key test-value 创建 /test-key根节点
create -e /test 111 创建临时节点, 注临时节点建不了子节点
create -s /test2 222 创建顺序节点
create -c /test3 333 创建容器节点
- ls / 输出如 [test, test20000000006, zookeeper]
- create -s /test20000000006/aaa 333
- Created /test20000000006/aaa0000000000
set /test-key test-value2 修改名为 /test-key的根节点的值
get /test-key 查看 /test-key的根节点的值
get -w /test-key 给节点 /test-key加上监听, 当被修改会收到通知
ls -w /test-key 监听目录, 当指定目录下生成了目录就会收到通知
delete /test-key 删除名为 /test-key的根节点, 前提是不能有子节点
deleteall /test-key 递归删除名为 /test-key的根节点

ACL(权限控制机制)

  • 权限仅对当前节点有效, 不会影响子节点也就是不会继承

4种认证方案(scheme)


- world(默认): 开放模式, 只有一个用户 anyone(表示任何人)
- ip: ip模式, 限定指定客户端 IP防问
- auth: 已认证用户模式, 此授权不针对任何特定ID, 而只要是在同一个会话中通过 addauth已认证过的用户都会被认可, 指定节点赋予权限之后认证的用户需要重新赋予权限到节点 setAcl /path auth::crwda; 此模式强依赖当前会话
- digest: 认证用户&密码(SHA1加密+Base64编码)模式, 不同于 auth模式可以在不同的会话中按用户账户+密码认证

5种操作权限(permission)


CREATE(c): 可以创建子节点
READ(r): 可以读取节点数据及显示子节点列表
WRITE(w): 可以设置节点数据
DELETE(d): 可以删除子节点(仅下一级节点)
ADMIN(a): 可以设置节点访问控制列表权限

权限相关命令


# 查看权限
- getAcl /test-path

# world(默认)模式示例
- setAcl /path world:anyone:<权限>
> 'world,'anyone
> : cdrwa

# auth模式示例
- addauth digest <用户名>:<明文密码>
- setAcl /path auth:<用户名>:<id 此项可以为空,即使指定了 id还是所有已授权用户>:<权限>
* 注必须存在已授权的用户, 如没有先通过 addauth认证用户, 否则报以下信息  Acl is not valid : /path

# digest模式示例
- addauth digest <用户名>:<明文密码>
- setAcl /path digest:<用户名>:<密码(SHA1加密+Base64编码)>:<权限>
* 生成加密密码: echo -n <user>:<password> | openssl dgst -binary -sha1 | openssl base64

# ip权限示例
- setAcl /path ip:<ip地址|地址段>:<权限>
- setAcl /path ip:192.168.1.10:cdrwa,ip:192.168.1.11:rw

## 多种授权模式
- setAcl /path ip:192.168.1.10:cdrwa,digest:shawn:ob/6q/NAEVVH6Zgn03ic1q7M3Y4=:rda,auth::cda

超级权限管理员

  • 超级用户可以无视任何权限用户的授权操作

$ vi bin/zkServer.sh
# 查找以下部分
    nohup "$JAVA" $ZOO_DATADIR_AUTOCREATE "-Dzookeeper.log.dir=${ZOO_LOG_DIR}" \
    "-Dzookeeper.log.file=${ZOO_LOG_FILE}" "-Dzookeeper.root.logger=${ZOO_LOG4J_PROP}" \

# 添加自定义的超级用户, 且保存重启 Zookeeper; 
    nohup "$JAVA" $ZOO_DATADIR_AUTOCREATE "-Dzookeeper.log.dir=${ZOO_LOG_DIR}" \
    "-Dzookeeper.log.file=${ZOO_LOG_FILE}" "-Dzookeeper.root.logger=${ZOO_LOG4J_PROP}" "-Dzookeeper.DigestAuthenticationProvider.superDigest=root:u53OoA8hprX59uwFsvQBS3QuI00=" \

# 授权 addauth digest root:123456

Watcher机制(观察与通知)

  • Zookeeper通过 Watcher监控每个 Znode发生的变化. 当 Znode发生变化时触发通知事件到指定分布式应用中(事件被触发后将自动从指定的 Znode节点中移除), 最后分布式应用收到通知后进行业务处理

Watcher工作过程& 特性

  1. 客户端设置 Watcher在指定 Znode节点上
  2. 指定的 Znode节点被更改时, 事件被触发通知指定客户端(事件被触发后将会从 Znode节点中移除)
  3. 当 Watcher事件触发时, Zookeeper会异步通过 Socket通知到客户端的, 在此过程中很有可能会有延时, 导致错过几次指定的 Znode节点的变化, 所以不能指望捕获节点每次的变化. 因此无法保证强一致性, 而只能保证最终的一致性
  4. 客户端的 Watcher回调执行过程是串行的

集群

服务角色

  1. Leader: 事务请求的唯一调度和处理者, 确保事务处理的顺序性
  2. Follower: 处理客户端的非事务请求, 转发事务请求给 Leader, 参与事务请求 Proposal的投票和 Leader选举投票
  3. Observer: 处理客户端的非事务请求, 转发事务请求给 Leader, 不参与任何形式的投票
  • 在完成了 Leader选举后, Learner(Follower和Observer的统称)会向 Leader进行注册. 然后进入数据同步环节

角色状态

  1. LOOKING: 寻找 Leader状态. 当处于该状态时, 未找到 Leader, 将会进入 Leader选举. 选举中, 集群是不对外提供服务的
  2. FOLLOWING: 跟随者状态. 表明当前服务器角色是 Follower
  3. LEADING: 领导者状态. 表明当前服务器角色是 Leader
  4. OBSERVING: 观察者状态. 表明当前服务器角色是 Observer

ZAB协议

  • ZAB(Zookeeper Atomic Broadcast)协议, 通过此协议 Zookeeper实现了主从架构, 维持了集群中各个副本之间的数据一致性
  • ZAB协议封装事务时会对每个事物分配一个全局自增id(ZXID)来保证事物的顺序
  • ZAB协议两个基本原则是 1)确保 Leader已提交的事物最终会被所有服务器提交 2)确保丢弃 Leader未提交的& 已被跳过的事物
  • ZAB协议有两种模式:
  1. 消息广播模式: 当 Leader接收到写请求时, 将请求封装成一个事务 Proposal, 再其发送给所有 Follower, 然后根据 Follower的反馈提交事物(需有半数以上 Follower返回 Ack信息), 以此保持集群之间的数据一致性

  2. 崩溃恢复模式: 当 Leader崩溃(如 Leader宕机, 重启, 网络故障等, 导致 Leader失去与过半 Follower联系)时进入崩溃恢复模式, 首先选举新的 Leader, 然后新的 Leader与 Follower进行数据同步, 当集群中过半数 Follower与新的 Leader完成数据同步之后, 将退出恢复模式进入消息广播模式, 开始接收客户端的事务请求

  • Leader选举详细过程

集群两种状态:

  1. 当已经存在 Leader: 此种情况一般是某一台服务器启动得较晚, 在其启动之前, 集群已经正常工作了, 启动同时该机试图去选举 Leader, 此时会被告知当前的 Leader信息, 所以仅仅需要和当前 Leader建立起连接同步即可
  2. 当不存在 Leader:
    (1) 第一轮投票, 每台机器都会将自己作为投票对象发给其它机器. 投票内容 例: (SID, ZXID) SID当前机器的唯一标识, ZXID事务ID
    (2) 第二轮投票, 每台机器都会根据 Leader选举算法规则来处理收到的投票:
     · vote_sid:接收到投票中所推荐的 Leader SID
     · vote_zxid:接收到投票中所推荐的 Leader ZXID
     · self_sid:自己的 SID
     · self_zxid:自己的 ZXID
     投票处理指的是(vote_sid, vote_zxid)(self_sid, self_zxid)的对比的过程
     规则一: 当 vote_zxid > self_zxid就认可当前收到的投票, 并再次将该投票发送出去
     规则二: 当 vote_zxid < self_zxid那么坚持自己的投票, 不做任何变更
     规则三: 当 vote_zxid = self_zxid那么就对比两者的SID, 当 vote_sid > self_sid那么就认可当前收到的投票, 并再次将该投票发送出去
     规则四: 当 vote_zxid = self_zxid, 且 vote_sid < self_sid那么坚持自己的投票, 不做任何变更
    (3) 确定 Leader, 通过多次统计投票后, 如果某一台机器收到了半数的相同投票, 那么这个投票对应的 SID机器, 将成为 Leader
    通常数据越新(ZXID越大)成为 Leader的可能性越大. 或当 ZXID相同时 SID越大机会越大
  • 数据同步(消息传递的方式同步数据)

数据同步流程: Learner向 Learder完成注册后 - 数据同步 - 同步确认

  • 数据同步通常分为四类:
     1. 差异化同步(DIFF同步)
     2. 回滚再差异化同步(TRUNC+DIFF同步)
     3. 回滚同步(TRUNC同步)
     4. 全量同步(SNAP同步)

如果您觉得有帮助,欢迎点赞哦 ~ 谢谢!!

©️2020 CSDN 皮肤主题: 创作都市 设计师:CSDN官方博客 返回首页