zookeeper集群知识点
文章目录
什么是zookeeper
ZooKeeper 是一个开源的分布式协调服务,基于google的chubby,ZooKeeper框架最初是在“Yahoo!”上构建的,用于以简单而稳健的方式访问他们的应用程序。 后来,Apache ZooKeeper成为Hadoop,HBase和其他分布式框架使用的有组织服务的标准。 例如,Apache HBase使用ZooKeeper跟踪分布式数据的状态。ZooKeeper 的设计目标是将那些复杂且容易出错的分布式一致性服务封装起来,构成一个高效可靠的原语集,并以一系列简单易用的接口提供给用户使用。它也是一个典型的分布式数据一致性解决方案.
缺点:
难以做到水平拓展(也就是动态加机器),它只能改配置以后全部重启或者按个重启
zookeeper的特性
特性 | 介绍 |
---|---|
顺序一致性 | 数据一致性,数据按照顺序分批入库 |
原子性 | 要么同时成功,要么同时失败,过半投票机制 |
单一视图 | 不管客户端连接到哪个服务器,所看到的数据都是一样的 |
可靠性 | 一单服务器端处理完一个事务请求,并且客户端获得了服务端的返回成功标志,那这个事务造成的变化会一直保存在服务器上 |
最终一致性(实时性) | 一个事务被成功提交成功以后,那么所有客户端从服务端读取的数据基本是一致的,是一个无限接近实时的. |
zookeeper主要提供了文件系统和通知机制,这两个也是它的核心.
zookeeper的数据模型
可以理解为文件系统,也就是树形结构,类似于操作系统的文件管理器,每一个节点称为:znode (是zookeeper中的最小数据单元,貌似最大是1M)。每一个znode上都可以保存数据和挂载子节点
四种节点以及特性:
节点类型 | 特性 |
---|---|
持久化节点(PERSISTENT) | 节点创建后会一直存在zookeeper服务器上,直到主动删除 |
持久化有序节点(PERSISTENT_SEQUENTIAL) | 每个节点都会为它的一级子节点维护一个顺序 |
临时节点(EPHEMERAL) | 临时节点的生命周期和客户端的会话保持一致。当客户端会话失效,该节点自动清理 |
临时有序节点(EPHEMERAL_SEQUENTIAL) | 在临时节点上多勒一个顺序性特性 |
zookeeper的常见应用场景
场景 | 依据 |
---|---|
发布订阅 | wacther机制和znode |
分布式锁 | 临时有序节点和wacther机制 |
分布式队列 | 临时有序节点 |
负载均衡 | 负载均衡算法和znode |
ID生成器 | 临时有序节点 |
统一命名服务 | znode |
master选举 | znodes |
等等 | … |
zookeeper集群角色
zookeeper一般都是由2n+1台服务器构成的,而这个2n+1不包含obsever节点,而集群为奇数主要是根据存活量以及吞吐量去考虑的.集群主要由三种角色构成如下表:
角色 | 职责 | 责任 |
---|---|---|
leader | 领导者 |
leader是zookeeper集群的核心节点, 1.它是事务请求的唯一调度和处理者,它要保证集群事务处理的顺序性; 2.它是集群内部各个服务器的调度者 |
follower | 跟随者 |
1.它主要处理客户端非事务请求,以及转发事务请求给leader,事务请求就是会让数据产生变化的请求; 2.参与事务请求提议的投票(客户端的一个事务请求,需要半数服务器投票通过以后才能通知leader去commit,leader会发起一个提案,要求follower去投票); 3.参与leader选举的投票,与2的投票不是一回事. |
observer | 观察者 | 观察zookeeper集群中的最新状态的变化并且将这些状态同步到observer服务器上,不参与投票,增加observer不会影响集群的事务处理能力,反而可以提升集群的非事务处理能力,也就是常说的读吞吐量. |
zookeeper的Watcher机制
zookeeper提供了分布式数据发布/订阅,zookeeper允许客户端向服务器注册一个watcher监听。当服务器端的节点触发指定事件的时候会触发watcher。服务端会向客户端发送一个事件通知
watcher的通知是一次性,一旦触发一次通知后,该watcher就失效
Watcher对应Event.EventType中的状态,Watcher的监听的事件类型如下:
type | 含义 |
---|---|
None(-1) | 空,也就是刚建立连接那会 |
NodeCreated(1) | 创建子节点触发 |
NodeDeleted(2) | 删除子节点触发 |
NodeDataChanged(3) | 修改触发 |
NodeChildrenChanged(4) | 更新子节点触发 |
连接状态对应Event.KeeperState中的状态:
状态 | 含义 |
---|---|
Expired | 在一定时间内客户端没有收到服务器的通知, 则认为当前的会话已经过期了。 |
Disconnected | 断开连接的状态 |
SyncConnected | 客户端和服务器端在某一个节点上建立连接,并且完成一次version、zxid同步 |
authFailed | 授权失败 |
zookeeper的会话
在 ZooKeeper 中,一个客户端连接是指客户端和服务器之间的一个 TCP 长连接。客户端启动的时候,首先会与服务器建立一个 TCP 连接,从第一次连接建立开始,客户端会话的生命周期也开始了。通过这个连接,客户端能够通过心跳检测与服务器保持有效的会话,也能够向Zookeeper服务器发送请求并接受响应,同时还能够通过该连接接收来自服务器的Watch事件通知。 Session的sessionTimeout值用来设置一个客户端会话的超时时间。当由于服务器压力太大、网络故障或是客户端主动断开连接等各种原因导致客户端连接断开时,只要在sessionTimeout规定的时间内能够重新连接上集群中任意一台服务器,那么之前创建的会话仍然有效.
会话状态如下:
状态 | 含义 |
---|---|
NOT_CONNECTED | 未连接 |
CONNECTING | 连接中 |
CONNECTED | 已连接 |
CLOSED | 关闭 |
注意点:
连接中和已连接之间是可以相互转换的
分桶策略:将类似的会话放在同一区块中进行管理,以便于Zookeeper对会话进行不同区块的隔离处理以及同一区块的统一处理。
分配原则:每个会话的“下次超时时间点”(ExpirationTime)
计算公式:
ExpirationTime = currentTime + sessionTimeout ExpirationTime
= (ExpirationTime_ / ExpirationInrerval + 1) * ExpirationInterval
ExpirationInterval 是指 Zookeeper 会话超时检查时间间隔,默认 tickTime
zookeeper的Server工作状态
服务器具有四种状态,分别是LOOKING、FOLLOWING、LEADING、OBSERVING。
状态 | 含义 |
---|---|
LOOKING | 寻找Leader状态。当服务器处于该状态时,它会认为当前集群中没有Leader,因此需要进入Leader选举状态。 |
FOLLOWING | 跟随者状态。表明当前服务器角色是Follower。 |
LEADING | 领导者状态。表明当前服务器角色是Leader。 |
OBSERVING | 观察者状态。表明当前服务器角色是Observer。 |
zookeeper的ACL权限
zookeeper提供控制节点访问权限的功能,用于有效的保证zookeeper中数据的安全性。避免误操作而导致系统出现重大事故.
ACL | 含义 |
---|---|
CREATE |
创建子节点的权限 (针对子节点的权限控制) |
READ | 获取节点数据和子节点列表的权限 |
WRITE | 更新节点数据的权限 |
DELETE |
删除子节点的权限 (针对子节点的权限控制) |
ADMIN | 设置节点ACL的权限 |
关于Scheme,标准格式是
[类型:数据:权限字符串]
权限scheme(类型) | 含义和用法 |
---|---|
ip | 指定的IP地址,类似白名单,ip:ip地址或号段:权限字符串crwda,就是上边的权限首字母小写 |
digest | 用户名和加密密码的格式,digest:用户名:加密的密码:权限字符串crwda |
auth | 用户名和明文密码格式,auth:用户名:密码:crwda |
world | 所有人都可以,world:anyone:权限字符串crwda |
super | 超级管理员权限 |
关于API(ZooDefs.Ids)的权限含义
ZooDefs.Ids | 含义 |
---|---|
OPEN_ACL_UNSAFE | 完全开放的ACL,任何连接的客户端都可以操作该属性znode |
CREATOR_ALL_ACL | 只有创建者才有ACL权限 |
READ_ACL_UNSAFE | 只能读取ACL |
ANYONE_ID_UNSAFE | ID代表任何人 |
AUTH_IDS | 可以设置ACL,代替了已经认证过客户端的IDs |
zookeeper的常用命令
命令 | 含义 |
---|---|
stat path [watch] | 查看node状态, stat 节点名 注册watcher |
set path data [version] | 更新数据,set 节点名 数据 版本号,默认-1,可以理解为乐观锁 |
ls path [watch] | 查看节点的子节点,没有stat信息, ls 节点名 注册watcher |
ls2 path [watch] | 查看节点的子节点和tat信息, ls2 节点名 注册watcher |
setAcl path acl | 设置节点权限 |
delete path [version] | 删除子节点,delete 节点名 版本号 |
get path [watch] | 获取节点内容和stat信息,get 节点名 注册watcher |
create [-s] [-e] path data acl | 以两种格式创建子节点,-e是临时节点,-s是有序节点,create -s/-e 节点名 数据 权限 |
getAcl path | 获取节点权限 |
… | … |
stat信息含义:
属性 | 含义 |
---|---|
cversion | 子节点的版本号 |
aclVersion | 表示acl的版本号,修改节点权限 |
dataVersion | 表示的是当前节点数据的版本号 |
czxid | 节点被创建时的事务ID |
mzxid | 节点最后一次被更新的事务ID |
pzxid | 当前节点下的子节点最后一次被修改时的事务ID |
ctime | 创建时间 |
mtime | 更新时间 |
ephemeralOwner | 创建临时节点的时候,会有一个sessionId 。 该值存储的就是这个sessionid |
dataLength | 数据值长度 |
numChildren | 子节点数 |
zookeeper集群的leader选举
zookeeper集群的leader选举与它可以实现的master选举是不一样的,leader选举是一个更为复杂的过程,而zookeeper提供了三种算法来实现集群的leader选举,主要有:leaderElection、authFasetLeaderElection、FastLeaderElection.集群默认采用的是FastLeaderElection算法,验证算法可以去查看一下zookeeper的源码,在源码的QUorumPeer.java中有一个同步的startLeaderElection方法,这个也是leader选举的入口,也算是看源码的入口之一.源码是用ant编译的,这里不过多说了.在这个startLeaderElection方法最后有一个createElectionAlgorithm(int electionAlgorithm)方法,点进去之后就可以看到对应的选举算法了.这里主要还是关注FastLeaderElection算法:
在FastLeaderElection算法中有几个主要的参数:
参数 | 作用 |
---|---|
serverid | 在配置集群的时候给定的服务器id,也就是myid文件中的数字 |
zxid | 服务器在运行时产生的数据id,而zxid越大表示数据越新,所以选举的时候它起到了很重要的作用 |
Epoch | 选举的轮数,表示的就是当前是进入到选举那一轮了,然后每次选举一轮他就自增1,是一个原子操作 |
ServerState | Looking、Following、Observering、Leadeing这四种状态 |
主要的选举过程可以看我的另一篇博文
zookeeper的leader选举过程
选举大致流程如下,如有错误欢迎指正:
ZAB协议
ZAB(ZooKeeper Atomic Broadcast 原子广播) 协议是为分布式协调服务 ZooKeeper 专门设计的一种支持崩溃恢复的原子广播协议。 在 ZooKeeper 中,主要依赖 ZAB 协议来实现分布式数据一致性,基于该协议,ZooKeeper 实现了一种主备模式的系统架构来保持集群中各个副本之间的数据一致性。
ZAB 协议主要分为两种基本的模式:崩溃恢复模式和消息广播模式
当zookeeper集群刚刚启动或者 Leader 服务器出现网络中断、崩溃退出与重启等异常情况时,ZAB 协议就会进入恢复模式并选举产生新的Leader服务器,同时集群中已经有过半的机器与该Leader服务器完成了状态同步(数据同步)之后,ZAB协议就会退出恢复模式,当集群中有过半的Follower服务器完成了和Leader服务器的状态同步,那么整个服务框架就会进入消息广播模式,而当进行拓展机器时,新加入的follower服务器在启动后就会自觉进入恢复模式,当然前提是leader还存活着,不然会去竞争leader,当接收到leader的广播之后会和leader建立连接进行数据同步,然后再一起进入消息广播正式工作.
在集群启动过程中会经历如下的状态
状态 | 含义 |
---|---|
LeaderElection(选举阶段) | 节点在一开始都处于选举阶段,只要有一个节点得到超半数节点的票数,它就可以当选准 leader。 |
Discovery(发现阶段) | 在这个阶段,followers 跟准 leader 进行通信,同步 followers 最近接收的事务提议。 |
Synchronization(同步阶段) | 同步阶段主要是利用 leader 前一阶段获得的最新提议历史,同步集群中所有的副本。同步完成之后 准 leader 才会成为真正的 leader。 |
Broadcast(广播阶段) | 到了这个阶段,Zookeeper 集群才能正式对外提供事务服务,并且 leader 可以进行消息广播。同时如果有新的节点加入,还需要对新节点进行同步。 |
原理
- 在zookeeper 的主备模式下,通过zab协议来保证集群中各个副本数据的一致性
- zookeeper使用的是单一的主进程来接收并处理所有的事务请求,并采用zab协议,把数据的状态变更以事务请求的形式广播到其他的节点
- zab协议在主备模型架构中,保证了同一时刻只能有一个主进程来广播服务器的状态变更
- 所有的事务请求必须由全局唯一的服务器来协调处理,这个的服务器叫leader,其他的叫follower,leader节点主要负责把客户端的事务请求转化成一个事务提议(proposal),并分发给集群中的所有follower节点,再等待所有follower节点的反馈(ack)。一旦超过半数服务器进行了正确的反馈,那么leader就会commit这条消息.
- (1)zab协议一定要保证已经被leader提交的事务也能够被所有follower提交;(2)而且需要保证在崩溃恢复过程中跳过哪些已经被丢弃的事务.
第5点的场景:
- 一个事务请求被leader处理并且广播给所有follower以后,follower节点也反馈会了ack给leader,并且leader也commit了,但是在leader把自己已经commit的消息广播出去之前,leader挂了.则事务可以被follower提交
- 一个事务请求被leader处理了,但是在广播给所有follower节点之前挂了,则事务要丢弃