赞
踩
上一篇我们介绍了Zookeeper的一些基础知识,本篇来讲解zk内部的一些核心原理,帮助我们更好的理解zk的工作机制。
目录
Zookeeper系列:
Leader选举是保证分布式数据一致性的关键所在。当Zookeeper集群中的一台服务器出现以下两种情况之一时,需要进入Leader选举。
服务器启动时期的Leader选举
若进行Leader选举,则至少需要两台机器,这里选取3台机器组成的服务器集群为例。在集群初始化阶段,当有一台服务器Server1启动时,其单独无法进行和完成Leader选举,当第二台服务器Server2启动时,此时两台机器可以相互通信,每台机器都试图找到Leader,于是进入Leader选举过程。选举过程如下:
过半机制(quorum):所谓“过半”是指大于集群机器数量的一半,即大于或等于(n/2+1)。但由于Observer不参与投票,因此此处的“集群机器数量”不包含Observer角色节点。
服务器运行时期的Leader选举
在Zookeeper运行期间,Leader与非Leader服务器各司其职,即便当有非Leader服务器宕机或新加入,此时也不会影响Leader,但是一旦Leader服务器挂了,那么整个集群将暂停对外服务,进入新一轮Leader选举,其过程和启动时期的Leader选举过程基本一致。例如还是上面的集群,2台server中已经完成了Leader选举,若此时加入一个新的server3则它会直接变成Follower,如果此时server2作为Leader宕机了,那么就会在server1和server3之间发起新的选举,流程和上面的类似。
服务器状态
zk集群中的服务器具有四种状态:
选票的数据结构
上面也提到了每个选票中包含了两个最基本的信息,所推举服务器的myid(服务器的唯一标识)和ZXID(事务ID),选票(Vote)在Zookeeper中包含字段如下
节点间的网络通信
每台zk服务器在启动的过程中,会启动一个QuorumPeerManager,负责各台服务器之间的底层Leader选举过程中的网络通信。
选举算法核心:FastLeaderElection
选票管理
算法核心
上图展示了FastLeaderElection模块是如何与底层网络I/O进行交互的。Leader选举的基本流程如下:
以上10个步骤就是FastLeaderElection的核心,其中步骤4-9会经过几轮循环,直到有Leader选举产生。
Zookeeper从设计模式角度来理解:是一个基于观察者模式设计的分布式服务管理框架,它负责存储和管理大家都关心的数据,然后接受观察者的注册,一旦这些数据的状态发生变化,Zookeeper就将负责通知已经在Zookeeper上注册的那些观察者做出相应的反应。
通知类似于数据库中的触发器, 对某个Znode设置Watcher, 当Znode发生变化的时候,WatchManager 会调用对应的Watcher。当Znode发生删除, 修改, 创建, 子节点修改的时候, 对应的Watcher 会得到通知。
Watcher的特点:
一次性触发: 一个 Watcher 只会被触发一次, 如果需要继续监听, 则需要再次添加Watcher;
事件封装: Watcher得到的事件是被封装过的, 包括三个内容 KeeperState(状态),EventType(事件类型),path(节点路径);
KeeperState | EventType | 触发条件 | 说明 |
---|---|---|---|
None | 连接成功 | ||
SyncConnected | NodeCreated | Znode被创建 | 此时处于连接状态 |
SyncConnected | NodeDeleted | Znode被删除 | 此时处于连接状态 |
SyncConnected | NodeDataChanged | Znode数据被改变 | 此时处于连接状态 |
SyncConnected | NodeChildChanged | Znode的子Znode数据被改变 | 此时处于连接状态 |
Disconnected | None | 客户端和服务端断开连接 | 此时客户端和服务器处于断开连接状态 |
Expired | None | 会话超时 | 会收到一个SessionExpiredException |
AuthFailed | None | 权限验证失败 | 会收到一个AuthFailedException |
使用客户端来创建一个和zk服务端连接的句柄,这就是一个会话(session)。Session一旦建立,状态就是连接中(CONNECTING)状态,然后客户端会尝试去连接zk服务端,连接成功之后状态变成已连接(CONNECTED)。一般正常情况下只会有这两个状态。不过,还是会发生一些无法恢复的错误/故障,比如:session过期,认证失败,或者客户端关闭连接,这种情况下,session状态会变成关闭(CLOSED)状态。Session会在不同的状态之间进行切换:CONNECTING, CONNECTED, RECONNECTING, RECONNECTED, CLOSE。
sessionID:会话ID,用来唯一标识一个会话,每次客户端创建会话的时候,ZooKeeper都会为其分配一个全局唯一的sessionID;
TimeOut:会话超时时间,如果客户端与服务器之间因为网络闪断导致断开连接,并在TimeOut时间内未连上其他server,则此次会话失效,此次会话创建的临时节点将被清理;
ExpirationTime:下次会话超时时间点。ZooKeeper会为每个会话标记一个下次会话超时时间点,便于对会话进行“分桶管理”,同时也是为了高效低耗的实现会话的超时检查与清理。其值接近于当前时间+TimeOut,但不完全相等,下面会介绍原因。
sessionID的前8位确定所在的机器,后56位使用当前时间的毫秒表示进行随机生成。
分桶管理
上面提到,zk会对每个会话标记一个下次会话超时时间点(ExpirationTime),便于对会话进行“分桶管理”。
每个会话创建完毕后,ZooKeeper就会为其计算ExpirationTime,计算方式大体如下:
ExpirationTime = CurrentTime(当前时间) + SessionTimeOut(会话超时时间)
但图中标识的ExpirationTime并不是以上公式简单的算出来的时间。因为在ZooKeeper的实际实现中,还做了一个处理。ZooKeeper的Leader服务器在运行期间会定时的进行会话超时检查,其时间间隔为ExpirationInterval(默认值2000毫秒),每隔2000毫秒进行一次会话超时检查。为了方便同时对多个会话进行超时检查,完整的ExpirationTime计算方式如下:
ExpirationTime_ = CurrentTime + SessionTimeOut
ExpirationTime = ( ExpirationTime_/ExpirationInterval + 1 ) * ExpirationInterval
注意:不要使用小学的乘法分配律把小括号给消化掉,其目的是为了保证ExpirationTime是ExpirationInterval的整数倍,带来的好处如下:
心跳机制
概念
事务:ZooKeeper中,能改变ZooKeeper服务器状态的操作称为事务操作。一般包括数据节点创建与删除、数据内容更新和客户端会话创建与失效等操作。对应每一个事务请求,ZooKeeper 都会为其分配一个全局唯一的事务ID,用 ZXID 表示,通常是一个64位的数字。每一个ZXID对应一次更新操作,从这些ZXID中可以间接地识别出ZooKeeper处理这些事务操作请求的全局顺序。
事务日志:所有事务操作都是需要记录到日志文件中的,可通过 dataLogDir配置文件目录,文件是以写入的第一条事务zxid为后缀,方便后续的定位查找。zk会采取“磁盘空间预分配”的策略,来避免磁盘Seek频率,提升zk服务器对事务请求的影响能力。默认设置下,每次事务日志写入操作都会实时刷入磁盘,也可以设置成非实时(写到内存文件流,定时批量写入磁盘),但那样在断电时会带来丢失数据的风险。事务日志记录的次数达到一定数量后,就会将内存数据库序列化一次,使其持久化保存到磁盘上,序列化后的文件称为"快照文件"。有了事务日志和快照,就可以让任意节点恢复到任意时间点。
数据快照:数据快照是zk数据存储中另一个非常核心的运行机制。数据快照用来记录zk服务器上某一时刻的全量内存数据内容,并将其持久化到指定的磁盘文件中,可通过dataDir配置文件目录。可通过参数snapCount来配置两次快照之间的事务操作个数,zk节点记录完事务日志时,会统计判断是否需要做数据快照(距离上次快照,事务操作次数等于[snapCount/2~snapCount] 中的某个值时,会触发快照生成操作,随机值是为了避免所有节点同时生成快照,导致集群运行缓慢)。
写流程
在 zookeeper 中,客户端会随机连接到 zookeeper 集群中的一个节点,如果是读请求,就直接从当前节点中读取数据,如果是写请求,那么请求会被转发给 leader 提交事务,然后 leader 会广播事务,只要有超过半数节点写入成功,那么写请求就会被提交(类似 2PC 事务)。
所有事务请求必须由一个全局唯一的服务器来协调处理,这个服务器就是 Leader 服务器,其他的服务器就是follower。
步骤如下:
Zab协议的全称是 Zookeeper Atomic Broadcast (Zookeeper原子广播)。ZooKeeper 能够保证数据一致性主要依赖于ZAB 协议的消息广播,崩溃恢复和数据同步三个过程。
Zab 协议的特性:
消息广播
消息广播类似一个分布式事务的两阶段提交模式。在这种模式下,无法处理因Leader在发起事务请求后节点宕机带来的数据不一致问题。因此ZAB协议引入了崩溃恢复机制。
崩溃恢复
当整个集群在启动时,或者Leader失联后,ZAB协议就会进入恢复模式,恢复模式的流程如下:
数据同步流程
Leader选举结束后,进入数据同步流程。数据同步流程以Leader数据为基础,让集群数据达到一致性状态。
希望本文对你有帮助,请点个赞鼓励一下作者吧~ 谢谢!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。