Zookeeper秒懂
Zookeeper 是一个开源的分布式的,为分布式框架提供协调服务的 Apache 项目。
工作机制
Zookeeper是一个基于观察者模式设计的分布式服务管理框架,它负责存储和管理大家都关心的数据,然后接受观察者的注册,一旦这些数据的状态发生变化,Zookeeper就将负责通知已经在Zookeeper上注册的那些观察者做出相应的反应。
特点
- Zookeeper:一个领导者(Leader),多个跟随者(Follower)组成的集群
- 集群中只要有半数以上节点存活,Zookeeper集群就能正常服务。所以Zookeeper适合安装奇数台服务器
- 全局数据一致:每个Server保存一份相同的数据副本,Client无论连接到哪个Server,数据都是一致的
- 更新请求顺序执行,来自同一个Client的更新请求按其发送顺序依次执行
- 数据更新原子性,一次数据更新要么成功,要么失败
- 实时性,在一定时间范围内,Client能读到最新数据
数据结构
ZooKeeper 数据模型的结构与 linux 文件系统很类似,整体上可以看作是一棵树,每个节点称做一个 ZNode。每一个 ZNode 默认能够存储 1MB 的数据,每个 ZNode 都可以通过其路径唯一标识
应用场景
1、统一命名服务
在分布式环境下,对应用/服务进行统一命名,便于识别
2、统一配置管理
分布式环境下,配置文件同步,保证所有节点的配置信息是一致的
3、统一集群管理
可以实现实时监控节点状态变化
4、发布和订阅
zk引入了watcher机制来实现发布/订阅功能,能够让多个订阅者同时监听某一个主题对象,当这个主题对象自身状态发生变化时,会通知所有订阅者
5、软负载均衡
在Zookeeper中记录每台服务器的访问数,让访问数最少的服务器去处理最新的客户端请求
安装
选举机制
当ZooKeeper集群中的一台服务器出现以下两种情况之一时,就会开始进入Leader选举:
1、服务器初始化启动
2、服务器运行期间无法和Leader保持连接
初始化启动
选举规则:
1、得票数超过集群数量的一半即可成为leader
2、把选票投给myid大的
3、一旦leader选举成功之后,其他节点只能是follower
简单记:投票过半数时,服务器 id 大的胜出
无法和Leader保持连接
当一台机器进入Leader选举流程时,当前集群可能会处于以下两种状态:
1、集群中有一个Leader,自身是follower,连接不上Leader;
2、自身是leader坏掉了,集群中不存在Leader
集群中已经存在一个Leader
机器试图去选举Leader时,会被告知当前服务器的Leader信息,对于该机器来说,仅仅需要和Leader机器建立连接,并进行状态同步即可
集群中不存在Leader
选举Leader规则:
1、EPOCH大的直接胜出
2、EPOCH相同,ZXID大的胜出
3、ZXID相同,SID大的胜出
EPOCH:
每个Leader任期的代号。没有Leader时同一轮投票过程中的逻辑时钟值是相同的。每投完一次票这个数据就会增加
ZXID:
事务ID。用来标识一次服务器状态的变更。在某一时刻,集群中的每台机器的ZXID值不一定完全一致,这和ZooKeeper服务器对于客户端"更新请求"的处理逻辑有关
SID:
服务器ID。用来唯一标识一台ZooKeeper集群中的机器,每台机器不能重复,和myid一致
举例:
假设ZooKeeper由5台服务器组成,SID分别为1、2、3、4、5,ZXID分别为8、8、8、7、7,并且此SID为3的服务器是Leader。
某一时刻,3和5服务器出现故障,因此开始进行Leader选举
选举时各机器状态:
Server1 (EPOCH:1,ZXID:8,SID:1)
Server2 (EPOCH:1,ZXID:8,SID:2)
Server4 (EPOCH:1,ZXID:7,SID:4)
开始选举:
Round one:EPOCH都相同无胜出
Round Two:ZXID Server4最小,Server1和Server2胜出
Round Thr:SID Server2大于Server1,Server2胜出
选举结果:
Server2为新的leader
节点类型
- 持续化节点
- 持续化顺序编号节点
- 临时节点
- 临时顺序编号节点
持久(Persistent):客户端和服务器端断开连接后,创建的节点不删除
短暂(Ephemeral):客户端和服务器端断开连接后,创建的节点自己删除
创建znode时设置顺序标识,znode名称后会附加一个值,顺序号是一个单调递增的计数器,由父节点维护,顺序号可以被用于为所有的事件进行全局排序,这样客户端可以通过顺序号推断事件的顺序
监听器原理
客户端注册监听它关心的目录节点,当目录节点发生变化(数据改变、节点删除、子目录节点增加删除)时,ZooKeeper 会通知客户端。
监听机制保证 ZooKeeper 保存的任何的数据的任何改变都能快速响应到监听了该节点应用程序
监听流程
- Zookeeper客户端,会创建两个线程,一个负责网络连接通信(connet),一个负责监听(listener)。
- 通过connect线程将注册的监听事件发送给Zookeeper服务端。
- Zookeeper服务端在注册监听器列表中将注册的监听事件添加到列表中。
- Zookeeper服务端监听到有数据或路径变化,就会将这个消息发送给listener线程。
- 客户端接收到通知后,会执行相应的回调方法来处理节点的变化。
写数据流程
客户端写数据请求提交给Leader节点流程
客户端写数据请求提交给Follower节点流程
Paxos算法
一种基于消息传递且具有高度容错特性的一致性算法
算法流程
在一个Paxos系统中,将所有节点划分为Proposer(提议者),Acceptor(接受者),和Learner(学习者)
注意:每个节点都可以身兼数职
-
Prepare准备阶段
Proposer生成全局唯一且递增的Proposal ID,向所有Acceptor发送Propose请求,这里无需携带提案内容,只携带Proposal ID即可 Acceptor收到Propose请求后,做出"两个承诺,一个应答" 不再接受Proposal ID小于等于当前请求的Propose请求 不再接受Proposal ID小于当前请求的Accept请求 不违背以前做出的承诺下,回复已经Accept过的提案中Proposal ID最大的那个提案的Value和Proposal ID,没有则返回空值
-
Accept接受阶段
Proposer收到多数Acceptor的Promise应答后,从应答中选择Proposal ID最大的提案的Value,作为本次要发起的提案。 如果所有应答的提案Value均为空值,则可以自己随意决定提案Value。然后携带当前Proposal ID,向所有Acceptor发送Propose请求 Acceptor收到Propose请求后,在不违背自己之前做出的承诺下,接受并持久化当前Proposal ID和提案Value
-
Learn学习阶段
Proposer收到多数Acceptor的Accept后,决议形成,将形成的决议发送给所有Learner
客户端命令
-
查看节点状态
stat <path>
czxid:创建节点的事务 zxid
每次修改 ZooKeeper 状态都会产生一个 ZooKeeper 事务 ID。事务 ID 是 ZooKeeper 中所有修改总的次序
ctime:
znode 被创建的毫秒数
mzxid:
znode 最后更新的事务 zxid
mtime:
znode 最后修改的毫秒数
pZxid:
znode 最后更新的子节点 zxid
cversion:
znode 子节点变化号,znode 子节点修改次数
dataversion:
znode 数据变化号
aclVersion:
znode 访问控制列表的变化号
ephemeralOwner:
如果是临时节点,这个是 znode 拥有者的 session id。如果不是临时节点则是 0
dataLength:
znode 的数据长度
numChildren:
znode 子节点数量
-
查看节点信息
ls <path>
-
创建节点
create <option> <path>
option:
-s:含有序列
-e:临时节点 -
获取节点信息
get <path>
-
删除节点
delete <path>
-
递归删除节点
deleteall <path>