什么是zookeeper?
官方文档上这么解释zookeeper,它是一个分布式协调框架,是Apache Hadoop 的一个子项目,它主要是用来解决分布式应用中经常遇到的一些数据管理问题,如:统一命名服务、状态同步服务、集群管理、分布式应用配置项的管理等。
文件系统数据结构:
监听通知机制
客户端注册监听它关心的任意节点,或者目录节点及递归子目录节点。
- 如果注册的是对某个节点的监听,则当这个节点被删除,或者被修改时,对应的客户端将被通知
- 如果注册的是对某个目录的监听,则当这个目录有子节点被创建,或者有子节点被删除,对应的客户端将被通知
- 如果注册的是对某个目录的递归子节点进行监听,则当这个目录下面的任意子节点有目录结构的变化(有子节点被创建,或被删除)或者根节点有数据变化时,对应的客户端将被通知。
**注意:**所有的通知都是一次性的,及无论是对节点还是对目录进行的监听,一旦触发,对应的监听即被移除。递归子节点,监听是对所有子节点的,所以,每个子节点下面的事件同样只会被触发一次。
Zookeeper 经典的应用场景
分布式锁
-
非公平锁
该锁在高并发的情况下,会存在性能下降问题,主要原因是所有连接都对同一个节点进行监听,当服务器检测到删除事件时,要通知所有的连接,所有的连接同时收到事件,再次并发竞争,这就是惊群效应。 -
公平锁
- 获取锁的服务先在/lock下创建一个临时有序节点。
- 判断刚创建的节点是否是最小节点,如果是则获得锁,不是则监听上一个节点。
- 或的锁的服务执行完成业务逻辑后删除自身节点,或触发下个节点的监听,重复第二步判断。
- 读写锁
(1)客户端调用 create 方法创建类似定义锁方式的临时顺序节点。
(2)客户端调用 getChildren 接口来获取所有已创建的子节点列表。
(3)判断是否获得锁,对于读请求如果所有比自己小的子节点都是读请求或者没有比自己序号小的子节点,表明已经成功获取共享锁,同时开始执行度逻辑。对于写请求,如果自己不是序号最小的子节点,那么就进入等待。
(4)如果没有获取到共享锁,读请求向比自己序号小的最后一个写请求节点注册 watcher 监听,写请求向比自己序号小的最后一个节点注册watcher 监听。
分布式配置中心
分布式注册中心
集群选举
- 在未进行选举是,每个节点都是looking状态,服务启动后去zookeeper立即去zk上创建/election/follower0临时节点,创建成功的服务则为leader。创建失败的服务会继续创建临时有序节点,服务状态为follower,并监听前一个节点。
- 当leader宕机后,最小的节点会自动删除,这时会触发下个节点的监听事件,下个节点会成为为leader。
- 当宕机的leader重连后,会作为follower节点创建临时有序节点。
Zookeeper 集群模式
Leader: 处理所有的事务请求(写请求),可以处理读请求,集群中只能有一个Leader。
Follower:只能处理读请求,同时作为 Leader的候选节点,即如果Leader宕机,Follower节点要参与到新的Leader选举中,有可能成为新的Leader节点。
Observer:只能处理读请求。不能参与选举。
zab协议
ZAB协议介绍
ZAB 协议全称:Zookeeper Atomic Broadcast(Zookeeper 原子广播协议)。
Zookeeper 是一个为分布式应用提供高效且可靠的分布式协调服务。在解决分布式一致性方面,Zookeeper 并没有使用 Paxos ,而
是采用了 ZAB 协议,ZAB是Paxos算法的一种简化实现。
zab协议支持:
- 崩溃恢复
- 原子广播
崩溃恢复
https://blog.csdn.net/nianqrzhanghw/article/details/121705275?spm=1001.2014.3001.5502
数据同步
当崩溃恢复之后,需要在正式工作之前(接收客户端请求),Leader 服务器首先确认事务是否都已经被过半的 Follwer 提交了,即是否完成了数据同步。目的是为了保持数据一致。
当 Follwer 服务器成功同步之后,Leader 会将这些服务器加入到可用服务器列表中。
实际上,Leader 服务器处理或丢弃事务都是依赖着 ZXID 的,那么这个 ZXID 如何生成呢?
答:在 ZAB 协议的事务编号 ZXID 设计中,ZXID 是一个 64 位的数字,其中低 32 位可以看作是一个简单的递增的计数器,针对客户端的每一个事务请求,Leader 都会产生一个新的事务 Proposal 并对该计数器进行 + 1 操作。
而高 32 位则代表了 Leader 服务器上取出本地日志中最大事务 Proposal 的 ZXID,并从该 ZXID 中解析出对应的 epoch 值(leader选举周期),当一轮新的选举结束后,会对这个值加一,并且事务id又从0开始自增。
高 32 位代表了每代 Leader 的唯一性,低 32 代表了每代 Leader 中事务的唯一性。同时,也能让 Follwer 通过高 32 位识别不同的Leader。简化了数据恢复流程。
基于这样的策略:当 Follower 连接上 Leader 之后,Leader 服务器会根据自己服务器上最后被提交的 ZXID 和 Follower 上的 ZXID进行比对,比对结果要么回滚,要么和 Leader 同步。
原子广播
ZAB 协议的消息广播过程使用的是一个原子广播协议,类似一个 两阶段提交过程。对于客户端发送的写请求,全部由 Leader 接收,Leader 将请求封装成一个事务 Proposal,将其发送给所有 Follwer ,然后,根据所有 Follwer 的反馈,如果超过半数(含leader自己)成功响应,则执行 commit 操作。