ZooKeeper基础理论知识 Paxos算法、ZAB协议、CAP定理(ZooKeeper学习笔记 1)

一、简介

ZooKeeper是一个开源的分布式应用程序协调服务器,其为分布式系统提供一致性服务。其一致性是通过基于Paxos算法的ZAB协议完成的。其主要功能包括:配置维护、域名服务、分布式同步、集群管理等。

二、ZooKeeper的一致性

1. 顺序一致性
从同一客户端发送的多个事务请求(写操作请求),最终会严格按照发起的顺序应用到ZooKeeper中
2. 原子性
在集群中所有事务在每一个Server上请求的结果是一致的。(例如当我们要做一个修改的操作时,那么我们的请求无论发送到集群中的哪一个节点上,最终得到的结果都是相同的)
3. 单一视图
无论客户端连接的是集群中的哪一个Server,读取到的数据模型都是一致的。
4. 可靠性
一旦某个事务被成功应用到了ZooKeeper,那么它将会被一直保留下来。
5. 最终一致性
当我们的一个事务被成功应用,Zookeeper可以保证在一段较短的时间内,客户端一定可以从服务端读取到最新的数据,但不能保证实时读取。(例如我们在集群中的节点上更改了一个数据的数值由0改为了1,那么其他的节点就会去同步这个修改的结果。但同步是需要一定时间的,所以如果此时有客户端从其他的结点访问这个数据,如果还没有同步完成那么用户是读取不到数据的。只有当同步完成时,用户才可以读取到数据。保证了一致性,但不能保证实时性)

三、Paxos算法

3.1 Paxos算法描述

Paxos算法的前提是信道是安全的、可靠的、集群结点间传递的消息是不会被窜改的。一般来说,在分布式系统中各个节点有两种通讯模型(共享内存和消息传递),Paxos算法才用消息传递的通讯模式。

3.2 Paxos算法中的三种角色

在paxos算法中有三种角色,分别具有三种不同的行为。但很多时候,一个进程同时充当多种角色。
Proposer:提案者
Acceptor:表决者
Learner:同步者

3.3 Paxos算法的一致性
  1. 每个提案者在提出提案时都会首先获取到一个具有全局唯一性的、递增的提案编号N,即在整个集群中是唯一的编号N,然后将该编号赋予其要提出的提案。
  2. 每个表决者在accept某提案后,会将该提案的编号N记录在本地,这样每个表决者中保存的已经被accept的提案中会存在一个编号最大的提案,其编号假设为maxN。每个表决者仅会accept编号大于自己本地maxN的提案。
  3. 在众多提案中最终只能有一个提案被选定。
  4. 一旦一个提案被选定,则其它服务器会主动同步(Learn)该提案到本地。
  5. 没有提案被提出则不会有提案被选定。
3.4 Paxos算法过程

Paxos算法共分为两个阶段:prepare阶段和accept阶段
prepare阶段

  1. 提案者(Proposer)准备提交一个编号为N的提议,于是其首先向所有表决者(Acceptor)发送prepare(N)请求,用于试探集群是否支持该编号的提议。
  2. 每个表决者(Acceptor)中都保存着自己曾经accept过的提议中的最大编号maxN。当一个表决者接收到其它主机发送来的prepare(N)请求时,其会比较N与maxN的值。有以下几种情况:
    (1)若N小于maxN,则说明该提议已过时,当前表决者采取不回应或回应Error的方式来拒绝该prepare请求
    (2)若N大于maxN,则说明该提议是可以接受的,当前表决者会首先将该N记录下来,并将其曾经已经accept的编号最大的提案Proposal(myid,maxN,value)反馈给提案者,以向提案者展示自己支持的提案意愿。其中第一个参数myid表示表决者Acceptor的标识id,第二个参数表示其曾接受的提案的最大编号maxN,第三个参数表示该提案的真正内容value。当然,若当前表决者还未曾accept过任何提议,则会将Proposal(myid,null,null)反馈给提案者。
    (3)在prepare阶段N不可能等于maxN。这是由N的生成机制决定的。要获得N的值,其必定会在原来数值的基础上采用同步锁方式增一。
    prepare阶段流程图如下所示,提案者(Proposer)本身也是一个表决者(Acceptor),表决同意。所以在下图中一共有4个节点,Acceptor1中自身保存的最大提案编号maxN大于当前提案编号N,没有回应拒绝了提案;Acceptor2中自身保存的最大提案编号maxN为0,也就是没有任何accept过任何提案,所以接受了当前提案;Acceptor3中自身保存的最大提案编号maxN小于当前提案编号N,所以接受了当前的提案。最终接受的节点总数为3,不接受的节点总数为1,接受的节点总数大于半数。所以改提案可以由prepare阶段进入到下一个accept阶段。
    在这里插入图片描述
    Accept阶段
    (1)当提案者(Proposer)发出prepare(N)后,若收到了超过半数的表决者(Accepter)的反馈,那么该提案者就会将其真正的提案Proposal(myid,N,value)发送给所有的表决者。
    (2)当表决者(Acceptor)接收到提案者发送的Proposal(myid,N,value)提案后,会再次拿出自己曾经accept的提议中的最大编号maxN,或曾经记录下的prepare的最大编号,让N与它们进行比较,若N大于等于这两个编号,则当前表决者accept该提案,并反馈给提案者。若N小于这两个编号,则表决者采取不回应或回应Error的方式来拒绝该提议。
    (3)若提案者没有接收到半数表决者accept的反馈。则会产生两种结果:一是放弃该提案不再提出;二是重新进入prepare阶段,递增提案号N,重新进入prepare阶段。
    (4)若提案者接收到的反馈数量超过了半数,则其会向外广播两类信息:一是像曾经的accept提案的表决者(Acceptor2和Acceptor3)发送“可执行数据同步信号”,即让他们执行其曾接收到的提案;二是向未曾向其发送accept反馈的表决者(Acceptor1)发送“ 提案+可执行数据同步信号”,即让他们接受到该提案后马上执行。
    在这里插入图片描述

四、ZAB协议

4.1 ZAB协议简介
  1. Zookeeper Atomic Broadcast,Zookeeper原子消息广播协议,是专为ZooKeeper设计的一种支持崩溃恢复的原子广播协议,在Zookeeper中,主要依赖ZAB协议来实现分布式数据的一致性。ZAB可以说是在Paxos算法的基础上发展而来
  2. Zookeeper使用一个单一主进程来接收并处理客户端的所有事务请求,即写请求。当服务器数据的状态发生变更后,集群采用ZAB原子广播协议,以事务提案Proposal的形式广播到所有的副本进程上。ZAB协议能够保证一个全局的变更序列,即可以为每一个事务分配一个全局的递增编号xid。
  3. 当Zookeeper客户端连接到Zookeeper集群的一个节点后,若客户端提交的是读请求,那么当前节点就直接根据自己保存的数据对其进行响应;如果是写请求且当前节点不是Leader,那么节点就会将该写请求转发给Leader,Leader会以提案Proposal的方式广播该写操作,只要有超过半数节点同意(ack)该写操作,则该写操作请求就会被Leader提交。然后Leader会再次广播commit给所有的订阅者即learner,通知他们同步最新的数据也就是将上一个事务进行提交。
  4. ZAB协议支持崩溃恢复可以保证在Leader节点崩溃后可以重新选举一个Leader并且保证数据的完整性。

如下所示为Zookeeper服务工作原理示意图:
在这里插入图片描述

4.2 ZAB中的三类角色

为了避免Zookeeper的单节点问题,所有Zookeeper是以集群的形式出现的。Zookeeper集群中共有三类角色:

  • Leader: 事务请求的唯一处理者,也可以处理读请求。
  • Follower: 可以直接处理客户端的读请求,并向客户端响应,但不会处理事务请求,其只会将客户端事务请求转发给Leader来处理;对于Leader发起的事务提案具有表决权;可以同步Leader中事务的处理结果;Leader选举过程中的参与者,具有选举权和被选举权。
  • Observer: 可以理解为不参与Leader选举的Follower,在Leader选举过程中没有选举权与被选举权;对于Leader的提案也没有表决权,用于协助Follower处理更多的客户端读请求。增加Observer可以提高集群处理读请求处理的能力。
4.3 ZAB中的三个重要数据
  • zxid: 类型为Long长度为64位,高32位标识epoch,低32位表示xid
  • epoch: 每次Leader选举过后都会生成一个新的epoch,在上一个epoch的基础上加1,然后将xid归零。
  • xid: 事务id,自动递增
4.4 ZAB中的三种模式
  • 恢复模式: 在集群启动的过程中,或Leader挂掉后,系统都需要进入恢复模式,以恢复系统对外提供服务的能力。无论是什么原因进入到恢复模式都包含两个重要的阶段:Leader选举与初始化同步。
  • 广播模式: 由Leader发出的广播分为初始化广播和更新广播。初始化广播也就是当Leader选举之后,新的Leader会广播自己新的epoch,并且让其他的节点从自己这里同步数据。更新广播也就是当有事务处理之后,需要其他的节点来同步数据,这时Leader就会发出更新广播通知其他的节点。
  • 同步模式: 分为初始化同步和更新同步。 Follower和Observer在收到初始化广播后就会进行初始化同步,Follower和Observer在收到更新广播后就会进行更新同步。
4.5 ZAB中的四种状态
  • **LOOKING:**选举状态。当处于恢复模式时所有的节点都处与LOOKING状态,直到选举出新的Leader
  • Following: Follower的正在工作状态
  • OBSERVING: Observer的正常工作状态
  • LEADING: Leader的正常工作状态
    ZooKeeper启动时所有节点初始状态为Looking,这时集群会尝试选举出一个Leader节点,选举出的Leader节点切换为Leading状态;当节点发现集群中已经选举出Leader则该节点会切换到Following状态,然后和Leader节点保持同步;当Leader节点挂掉时Follower节点则会切换到Looking状态,开始新一轮选举;
4.6 ZAB崩溃恢复
4.6.1 Leader选举

选举阶段必须确保选出的Leader具有最新的epoch和最大ZXID,否则在Recovery阶段无法保证数据的一致性。所以在选举的过程中会对每个Follower节点的ZXID进行对比只有拥有最大ZXID的Follower才可能当选Leader;选举过程中只要得到半数以上的支持就会成为新的leader节点。

4.6.2 数据恢复

完成选举后,在接收客户端新的事务请求之前,Leader 服务器会首先确认事务日志中的所有的 Proposal 是否已经被集群中过半的服务器 Commit。Leader 需要确保所有的 Follower 能够接收到每一条事务的 Proposal ,并且能将所有已经提交的事务 Proposal 应用到内存数据中。等到 Follower 将所有尚未同步的事务 Proposal 都从 Leader 服务器上同步完成,并且应用到内存数据中以后,Leader 才会把该 Follower 加入到真正可用的 Follower 列表中。

五、 CAP定理

CAP定理指出在一个分布式的系统中不可能同时满足以下三点:
一致性(Consistency):
当写操作完成后,读操作必须返回该值。例如我们修改了一个数值由0改为了1,那么当客户端从任意一个节点读取这个数据时,返回的都必须是1,如果返回0就不满足一致性的要求。
可用性(Availablity):
系统中的可用节点在收到客户端的请求之后,必须要做出响应。
分区容错性(Partition tolerance):
允许区间通信失败的情况发生,也就是两个分区之间想要同步最新的数据,但是可能因为各种情况导致消息发送失败。一般来说这种情况是无法避免的,对于一个分布式系统而言都要接受这种情况。

之所以说CAP三者不能同时满足,是因为一致性和可用性是相互矛盾的。例如我们现在有两个节点,节点1再进行写操作将0改为1,此时我们向节点2读这个数据,如果要满足一致性那么就要等待节点2将数据同步完成才可以访问,但是可用性又要求节点2必须做出响应,如果此时做出响应返回的结果就是0,又违背了一致性的要求,所以二者是相互矛盾的。

结论: 所以如何权衡A和C就要根据实际的业务需求,如果对可用性要求高就要放弃一致性,例如微博可用性就要高于一致性。而对于一致性要求高就要放弃可用性,例如银行如果不能保证一致性那么在转账取款等场景时就会出现严重的问题。

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值