Zookeeper原理详解
2023-07-04 08:42:16 0 举报
AI智能生成
知识要点和原理解析,详细信息和图片均在黄色图标的注释中,鼠标移动到黄色图标上即会显示,图片加载有时较慢。
作者其他创作
大纲/内容
简介
zk是什么
ZooKeeper 是一个开源的分布式协调服务框架
应用场景
分布式锁服务
排它锁
锁的释放
客户端主动将临时ZNode删除
客户端发生宕机
共享锁
分布式锁的实现
具体实现步骤
如果当前节点是读
如果当前节点是写
与redis比较
基于 Zookeeper 的锁安全吗?
数据的发布/订阅
具体步骤
使用场景
数据量通常较小
数据内容在运行时会发生动态变化
集群中各机器共享,配置一致
负载均衡
典型场景:动态DNS服务
命名服务
具体实现步骤
分布式协调/通知
使用场景
心跳检测
Master选举
实现步骤
集群管理
设计目标
最终一致性
可靠性
实时性
等待无关(wait-free)
原子性
顺序性
全局有序
偏序两种
ZooKeeper 中节点
机器节点
数据节点(ZNode )
节点类型
持久节点
持久顺序节点
临时节点
临时顺序节点
节点信息
data
ACL
child
stat
节点原子性更新
乐观锁
集群角色
Leader
Follower
Observer
会话(session)
Watcher(事件监听器)
ACL(Access Control Lists)
五种权限
CREATE
READ
WRITE
DELETE
ADMIN
顺序访问
高性能高可用
ZAB协议
两种模式
崩溃恢复
消息广播
两阶段提交保证消息一致性
为每个follower提供FIFO(先进先出)单独队列保证消息顺序性
角色和作用
三种角色
Leader(领导者)
Leader在集群中只有一个节点
作用
在ZAB崩溃恢复之后,消息广播之前,进行集群中的数据同步
维持与Follower的心跳,接收Follower请求消息,并据不同的消息类型,进行不同的处理
消息类型
PING消息
REQUEST消息
ACK消息
REVALIDATE消息
Follower(跟随者)
作用
与Leader保持心跳连接
当Leader挂了的时候,经过投票后成为新的leader
向Leader发送请求(PING请求、REQUEST消息、ACK请求、REVALIDATE消息)
处理leader发来的消息与请求
接收Client的请求,如果为写请求,发送给Leader
返回Client请求结果
Observer(观察者)
作用
提高zookeeper集群的读性能
提高伸缩性,同时还不影响吞吐率
Observer不参与投票过程,只同步 leader的状态
Observers 接受客户端的连接,并将写请求转发给 leader节点
四种状态
LOOKING
FOLLOWING
LEADING
OBSERVING
znode详解
Znode的类型分为三类
持久节点(persistent node)
临时节点(ephemeral node)
顺序节点(sequential node)
四种形式
PERSISTENT 持久节点
PERSISTENT_SEQUENTIAL(持久顺序节点/s0000000001)
EPHEMERAL 临时节点
EPHEMERAL_SEQUENTIAL(临时顺序节点/s0000000001)
ZooKeeper 3.5.x 中引入了 container 节点 和 ttl 节点(不稳定)
container
ttl
Znode属性
stat属性
Zxid详解
版本号详解
节点特性
同一级节点 key 名称是唯一的
创建节点时必须使用全路径
当客户端与服务器端断开连接时,临时节点将会被删除
节点具有watch 机制,可以监听节点变化
删除节点只能一级一级删除
session会话管理
Session简介
会话创建
4个基本属性
SessionId:会话ID
TimeOut:会话超时时间
TickTime:下次会话超时时间点
isClosing:标记会话是否已经被关闭
会话状态
Connecting:正在连接
Connected:已连接
ReConnecting:正在重连
ReConnected:已经重连
Close:连接关闭
sessionId
SessionTracker:服务端的会话管理器
会话创建
1、处理 ConnectRequest 请求
2、会话创建
3、处理器链路处理
4、会话响应
会话管理
分桶策略
下次超时时间点:nextExpirationTime
过期时间是ExpirationInterval的倍数
会话激活
过期时间的更新,就意味着Session需要在桶之间迁移
触发时机
只要客户端向服务端发送请求,包括读请求和写请求,那么就会触发一次会话激活
主动发起PING 请求
会话重连
两类异常
CONNECTION_LOSS:连接断开
SESSION_EXPIRED:会话过期
重连之后的两种状态
Connected
Expired
会话超时检查
如何定时检查
过期会话清理
步骤
1、标记会话状态为 “已关闭”
2、发起 “会话关闭” 请求
3、收集需要清理的临时节点
4、添加 “节点删除” 事务变更
5、删除临时节点
6、移除会话
7、关闭 NIOServerCnxn
Watcher机制
Watcher特性
一次性
客户端顺序回调
轻量级
时效性
Watcher主要结构体
Watcher 接口
WatchedEvent
常见的 KeeperState 和 EventType 组合
getWrapper()
Watch 机制是如何实现的
注册方式
new ZooKeeper(String connectString, int sessionTimeout, Watcher watcher)
getData、exists 和 getChildren
触发通知的条件
zk连接类型及事件类型
客户端 Watch 注册实现过程
ZooKeeper 客户端主要做了两个工作
标记该会话是一个带有 Watch 事件的请求
将 Watch 事件存储到 ZKWatchManager
getData 接口为例
DataWatchRegistration保存 watcher 事件和节点的对应关系
构造packet对象 并将其加入到outgoingQueue队列(阻塞队列)
SendThread 线程类处理请求发送
SendThread 不仅仅用于发送消息,实际上其也负责接收消息
注册wacth到client的ZKWatchManager
Outgoingqueue, pendingQueue和EventThread的event等待队列关系
流程图
数据包packet流向图
到目前为止,客户端就有如下三条线程了
主线程:负责处理用户在控制台输入命令
守护线程1: seadThread
守护线程2: eventThread
服务端 Watch 注册实现过程
服务器的请求处理器链
PrepRequestProcessor:只是做了会话的校验,没有实质的处理
SyncRequestProcessor:会进行日志回滚和生成快照
FinalRequestProcessor:处理客户端请
服务端处理 Watch 事件基本有 2 个过程
解析收到的请求是否带有 Watch 注册事件
将对应的 Watch 事件存储到 WatchManager
WatchManager
源码解析
processRequest
getData()
ServerCnxn解析
服务端 Watch 事件的触发过程
setData 接口
triggerWatch方法
process方法
基本流程
客户端回调的处理过程
readResponse方法
queueEvent方法
事件处理线程
按顺序处理响应
羊群效应
举例
解决方法
步骤
zab协议
一致性
zookeeper中保证数据一致性用的是ZAB协议
顺序一致性
原子性
系统视图唯一性
持久性
及时性
zk一致性保证的是
写请求是线性一致性的,读不是
任何给定的client操作的执行顺序是由client来决定的,其称之为FIFO Client Order
工作方式
FIFO client order会应用于单个client的所有请求
zk没有保证跨客户端的强一致性
两个情况
leader执行commit了,还没来得及给follower发送commit的时候,leader宕机了
leader的事务性请求已经在部分节点(不是全部)应用了,这个时候leader挂掉了
特性
Zab 协议需要确保那些已经在 Leader 服务器上提交(Commit)的事务最终被所有的服务器提交。
Zab 协议需要确保丢弃那些只在 Leader 上被提出而没有被提交的事务。
工作流程(图)
Zab协议核心
定义了事务请求的处理方式
1、所有的事务请求必须由一个全局唯一的服务器来协调处理,这样的服务器被叫做Leader服务器。其他剩余的服务器则是Follower服务器。
2、Leader服务器 负责将一个客户端事务请求,转换成一个事务Proposal,并将该 Proposal 分发给集群中所有的 Follower 服务器,也就是向所有 Follower 节点发送数据广播请求(或数据复制)
ZXID 是如何生成的
图解
上个leader发布Proposal后未提交就宕机了,新的Proposal在部分follower中已写入但未提交
3、分发之后Leader服务器需要等待所有Follower服务器的反馈(Ack请求),在Zab协议中,只要超过半数的Follower服务器进行了正确的反馈后(也就是收到半数以上的Follower的Ack请求),那么 Leader 就会再次向所有的 Follower服务器发送 Commit 消息,要求其将上一个 事务proposal 进行提交。
顺序一致性
问题
ZooKeeper 集群的写入是由 Leader 结点协调的,真实场景下写入会有一定的并发量,那 Zab 协议的两阶段提交是如何保证事务严格按顺序生效的
Leader 是如何判断当前 ZXID 之前是否还有未提交提案的
leader顺序性
处理队列(包括读写)+ 写等待
follower顺序性
提案下发阶段:leader下发提案到follower时
对比新提案的 ZXID 与自身最新 ZXID 是否相差“1”,来保证事务顺序生效
提交阶段:leader下发commit时
通过对比commit request的zxid和pendingTxns的zxid
步骤
总之:Follower通过队列和zxid等顺序标识保证请求的顺序处理,一言不合就会退出或者重新同步Leader。
client回调顺序性
按序出队
比较xzid
zookeeper如何保证半数提交后剩下的节点上最新的数据
剩下的节点,会进行版本比对,发现版本不一致的话,会更新节点的数据(退出重新同步)
Zab 模式
崩溃恢复
广播模式
四个阶段
选举(election)
两种情况
集群启动期间Leader选举
集群运行期间Leader故障
选举投票规则
根据事务ID(zxid)
zxid相同时看myId
syncLimit时间限制
选举算法
1、每个服务器给自己投票
2、比较投票
3、票数是否过半
步骤总结
发现(discovery)
同步(sync)
广播(Broadcast)
崩溃恢复模式
ZAB的保证
Zab 协议需要确保那些已经在 Leader 服务器上提交(Commit)的事务最终被所有的服务器提交。
Zab 协议需要确保丢弃那些只在 Leader 上被提出而没有被提交的事务。
针对以上的两个要求,在进行 Leader 选举时,只需要选举出集群中 ZXID 最大的事务 Proposal 即可,这样就可以省去 Leader 服务器检查 Proposal 的提交和丢弃工作了。因为 Leader 服务器的事务是最大的,一切以 Leader 服务器的数据为标准即可。
流程
恢复(Recovery)
数据同步策略
SNAP
DIFF
TRUNC
TRUNC+DIFF
消息广播模式
二阶段提交
过程
交互图
广播 流程图
请求的按序处理
脑裂问题
避免脑裂现象的限制条件
集群中存活的节点数必须要超过总节点数的半数才能继续提供服务
zk推荐奇数台集群搭建
原因
发生网络分层时,不会发生两层节点数相同,集群无法服务的现象
与偶数个节点比,容灾能力一样但更节省资源
最小节点数quorum小,响应速度快
问题
那些没有收到commit消息的follower怎么最终和leader数据保持一致
leader执行commit了,还没来得及给follower发送commit的时候,leader宕机了,这个时候如何保证数据一致性
客户端把消息写到leader了,但是leader还没发送proposal消息给其他节点,这个时候leader宕机了,leader宕机后恢复的时候此消息又该如何处理
同一个客户端,先发出写请求,leader将写请求事务广播给follow,如果半数follow成功,但是发出请求的follow没有成功,按照半数即成功的原理,leader会返回写操作成功,此时该客户端再读取数据,导致读取到的是旧的值,是不是不符合同一个session写后读的保证?
多个客户端读到的数据不一致
ZooKeeper 负载均衡和 Nginx 负载均衡有什么区别
集群最少要几台机器,集群规则是怎样的?集群中有 3 台服务器,其中一个节点宕机,这个时候 Zookeeper 还可以使用吗?
集群支持动态添加机器吗
Zookeeper对节点的watch监听通知是永久的吗?为什么不是永久的
zk持久化
内存中的数据
事务日志
日志文件
数据快照
为什么需要快照
快照数据主要时为了快速恢复
数据恢复
恢复数据的时候,先恢复快照数据,再通过增量恢复事务日志中的数据。
缺点
非高可用
zookeeper master就只能照顾一个机房
选举过程速度很慢且zk选举期间无法对外提供服务
zk的性能有限
zk本身的权限控制非常薄弱
羊群效应
羊群效应解决方法
0 条评论
下一页