ZooKeeper基础整理(一)
程序员文章站
2024-02-19 14:52:40
...
ZooKeeper基础整理一
概述
- ZooKeeper是分布式协调服务程序, 可以实现分布式协调/通知, 命名服务, 负载均衡, 分布式同步, 微服务的注册中心, 配置中心等, 同时它也提供缓存服务, 但不同于 Redis, ZooKeeper的键是树形层次结构, 它主要用来存储协调状态以及中心配置等信息, 且每个节点的存放数据上限为1M.
基本特性
- 原子性(Atomicity)
- 唯一视图(Single System Image), 最终一致性: 无论连接到哪个服务器, 看到的都是同一个视图
- 顺序一致性(Sequential Consistency): 同一个客户端的更新请求是按顺序执行的
节点(Znode)
- Zookeeper的数据模型是树形层次结构, 类似于文件系统, 不同在于任何节点都有自己的命名空间, 且也可以创建子节点, 而文件系统中只有文件节点可以存放数据, 目录节点不行
节点特点
- 所有节点都维护着 Metadata(元数据), ACL(Access Control List访问控制列表, 权限控制机制), 时间戳等, 又有文件系统的目录特点可以拥有子节点
- 可以存的数据上限为1M
- 键的格式是 Unix/Linux路径形式, 开头必须是由
/
(斜杠)来开头. 如果路径重复, 将会被覆盖
节点类型
- Persistent(持久节点): 永久保存, 除非手动删除
- Ephemeral(临时节点): 与客户端的会话生命周期有关, 当会话失效, 临时节点就会被删除
- Persistent_Sequential(持久顺序节点): 与 Persistent(持久节点)基本特性相同, 又有顺序属性, 节点名后边会自动追加一个由父节点维护的自增长整型数字.(格式为10位数字, 例
0000000001
) - Ephemeral_Sequential(临时顺序节点): 与 Ephemeral(临时节点)基本特性相同, 又有顺序属性, 节点名后边会自动追加一个由父节点维护的自增长整型数字
节点信息
[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 创建顺序节点
- ls / 输出如 [test, test20000000006, zookeeper]
- create -s /test20000000006/aaa 333
- Created /test20000000006/aaa0000000000
set /test-key test-value2 修改名为 /test-key的根节点的值
get /test-key 查看 /test-key的根节点的值
delete /test-key 删除名为 /test-key的根节点, 前提是不能有子节点
deleteall /test-key 递归删除名为 /test-key的根节点
Watcher机制(观察与通知)
- Zookeeper通过 Watcher监控每个 Znode发生的变化. 当 Znode发生变化时触发通知事件到指定分布式应用中(事件被触发后将自动从指定的 Znode节点中移除), 最后分布式应用收到通知后进行业务处理
Watcher工作过程& 特性
- 客户端设置 Watcher在指定 Znode节点上
- 指定的 Znode节点被更改时, 事件被触发通知指定客户端(事件被触发后将会从 Znode节点中移除)
- 当 Watcher事件触发时, Zookeeper会异步通过 Socket通知到客户端的, 在此过程中很有可能会有延时, 导致错过几次指定的 Znode节点的变化, 所以不能指望捕获节点每次的变化. 因此无法保证强一致性, 而只能保证最终的一致性
- 客户端的 Watcher回调执行过程是串行的
集群
服务角色
- Leader: 事务请求的唯一调度和处理者, 确保事务处理的顺序性
- Follower: 处理客户端的非事务请求, 转发事务请求给 Leader, 参与事务请求 Proposal的投票和 Leader选举投票
- Observer: 处理客户端的非事务请求, 转发事务请求给 Leader, 不参与任何形式的投票
- 在完成了 Leader选举后, Learner(Follower和Observer的统称)会向 Leader进行注册. 然后进入数据同步环节
角色状态
- LOOKING: 寻找 Leader状态. 当处于该状态时, 未找到 Leader, 将会进入 Leader选举. 选举中, 集群是不对外提供服务的
- FOLLOWING: 跟随者状态. 表明当前服务器角色是 Follower
- LEADING: 领导者状态. 表明当前服务器角色是 Leader
- OBSERVING: 观察者状态. 表明当前服务器角色是 Observer
ZAB协议
- ZAB(Zookeeper Atomic Broadcast)协议, 通过此协议 Zookeeper实现了主从架构, 维持了集群中各个副本之间的数据一致性
- ZAB协议封装事务时会对每个事物分配一个全局自增id(ZXID)来保证事物的顺序
- ZAB协议两个基本原则是 1)确保 Leader已提交的事物最终会被所有服务器提交 2)确保丢弃 Leader未提交的& 已被跳过的事物
- ZAB协议有两种模式:
-
消息广播模式: 当 Leader接收到写请求时, 将请求封装成一个事务 Proposal, 再其发送给所有 Follower, 然后根据 Follower的反馈提交事物(需有半数以上 Follower返回 Ack信息), 以此保持集群之间的数据一致性
-
崩溃恢复模式: 当 Leader崩溃(如 Leader宕机, 重启, 网络故障等, 导致 Leader失去与过半 Follower联系)时进入崩溃恢复模式, 首先选举新的 Leader, 然后新的 Leader与 Follower进行数据同步, 当集群中过半数 Follower与新的 Leader完成数据同步之后, 将退出恢复模式进入消息广播模式, 开始接收客户端的事务请求
- Leader选举详细过程
集群两种状态:
- 当已经存在 Leader: 此种情况一般是某一台服务器启动得较晚, 在其启动之前, 集群已经正常工作了, 启动同时该机试图去选举 Leader, 此时会被告知当前的 Leader信息, 所以仅仅需要和当前 Leader建立起连接同步即可
- 当不存在 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同步)
如果您觉得有帮助,欢迎点赞哦 ~ 谢谢!!