设为首页 收藏本站
查看: 1205|回复: 0

[经验分享] ZooKeeper系列补充Paxos

[复制链接]

尚未签到

发表于 2015-9-6 11:48:33 | 显示全部楼层 |阅读模式
Paxos算法与Zookeeper分析
一、Paxos算法
1.1 基本定义
  (1) 算法中的参与者主要分为三个角色,同时每个参与者又可兼领多个角色:
  ① proposer 提出提案,提案信息包括提案编号和提议的value;
  ② acceptor 收到提案后可以接受(accept)提案;
  ③ learner 只能"学习"被批准的提案;
  (2) 算法保证一致性的基本语义:
  ① 决议(value)只有在被proposers提出后才能被批准(未经批准的决议称为"提案(proposal)");
  ② 在一次Paxos算法的执行实例中,只批准(chosen)一个value;
  ③ learners只能获得被批准(chosen)的value;
  (3) 有上面的三个语义可演化为四个约束:
  ① P1:一个acceptor必须接受(accept)第一次收到的提案;
  ② P2a:一旦一个具有value v的提案被批准(chosen),那么之后任何acceptor 再次接受(accept)的提案必须具有value v;
  ③ P2b:一旦一个具有value v的提案被批准(chosen),那么以后任何 proposer 提出的提案必须具有value v;
  ④ P2c:如果一个编号为n的提案具有value v,那么存在一个多数派,要么他们中所有人都没有接受(accept)编号小于n的任何提案,要么他们已经接受(accpet)的所有编号小于n的提案中编号最大的那个提案具有value v;
1.2 基本算法(basic paxos)
  算法(决议的提出与批准)主要分为两个阶段:
  (一) prepare阶段:  
  (1) 当Porposer希望提出方案V1,首先发出prepare请求至大多数Acceptor。Prepare请求内容为序列号<SN1>;
  (2) 当Acceptor接收到prepare请求<SN1>时,检查自身上次回复过的prepare请求<SN2>
  如果SN2>SN1,则忽略此请求,直接结束本次批准过程;
   否则检查上次批准的accept请求<SNx,Vx>,并且回复<SNx,Vx>;如果之前没有进行过批准,则简单回复<OK>;
  (二) accept批准阶段:  
  (1) 经过一段时间,收到一些Acceptor的回复,回复可分为以下几种:
  ① 回复数量满足多数派,并且所有的回复都是<OK>,则Porposer发出accept请求,请求内容为议案<SN1,V1>;
  ② 回复数量满足多数派,但有的回复为:<SN2,V2>,<SN3,V3>……则Porposer找到所有回复中超过半数的那个,假设为<SNx,Vx>,则发出accept请求,请求内容为议案<SN1,Vx>;
  ③ 回复数量不满足多数派,Proposer尝试增加序列号为SN1+,转1继续执行;
  (2) 经过一段时间,收到一些Acceptor回复,回复可分为以下几种:
  ① 回复数量满足多数派,则确认V1被接受;
  ② 回复数量不满足多数派,V1未被接受,Proposer增加序列号为SN1+,转1继续执行;
  (3) 在不违背自己向其他proposer的承诺的前提下,acceptor收到accept 请求后即接受并回复这个请求。
1.3 算法优化(fast paxos)
  Paxos算法在出现竞争的情况下,其收敛速度很慢,甚至可能出现活锁的情况。例如,当有三个及三个以上的proposer在发送prepare请求后,很难有一个proposer收到半数以上的回复而不断地执行第一阶段的协议。因此,为了避免竞争,加快收敛的速度,在算法中引入了一个Leader这个角色,在正常情况下同时应该最多只能有一个参与者扮演Leader角色,而其它的参与者则扮演Acceptor的角色,同时所有的人又都扮演Learner的角色。
  在这种优化算法中,只有Leader可以提出议案,从而避免了竞争。使得算法能够快速地收敛而趋于一致,此时的paxos算法在本质上就退变为两阶段提交协议。但在异常情况下,系统可能会出现多Leader的情况,但这并不会破坏算法对一致性的保证,此时多个Leader都可以提出自己的提案,优化的算法就退化成了原始的paxos算法。
  一个Leader的工作流程主要有分为三个阶段:
   学习阶段 向其它的参与者学习自己不知道的数据(决议);
  ② 同步阶段 让绝大多数参与者保持数据(决议)的一致性;
  ③ 服务阶段 为客户端服务,提议案;
  图 1.1 Leader工作流程图
DSC0000.png
  (1) 学习阶段
  当一个参与者成为了Leader之后,它应该需要知道绝大多数的paxos实例,因此就会马上启动一个主动学习的过程。假设当前的新Leader早就知道了1-134、138和139的paxos实例,那么它会执行135-137和大于139的paxos实例的第一阶段。如果只检测到135和140的paxos实例有确定的值,那它最后就会知道1-135以及138-140的paxos实例。
  (2) 同步阶段
  此时的Leader已经知道了1-135、138-140的paxos实例,那么它就会重新执行1-135的paxos实例,以保证绝大多数参与者在1-135的paxos实例上是保持一致的。至于139-140的paxos实例,它并不马上执行138-140的paxos实例,而是等到在服务阶段填充了136、137的paxos实例之后再执行。这里之所以要填充间隔,是为了避免以后的Leader总是要学习这些间隔中的paxos实例,而这些paxos实例又没有对应的确定值。
  (3) 服务阶段
  Leader将用户的请求转化为对应的paxos实例,当然,它可以并发的执行多个paxos实例,当这个Leader出现异常之后,就很有可能造成paxos实例出现间断。
  (4) 问题
  ① Leader的选举原则
  ② Acceptor如何感知当前Leader的失败,客户如何知道当前的Leader
  ③ 当出现多Leader之后,如何kill掉多余的Leader
  ④ 如何动态的扩展Acceptor
二、Zookeeper
2.1 整体架构
  在Zookeeper集群中,主要分为三种角色,而每一个节点同时只能扮演一种角色,这三种角色分别是:
  ① Leader 接受所有Follower的提案请求并统一协调发起提案的投票,负责与所有的Follower进行内部的数据交换(同步);
  ② Follower 直接为客户端服务并参与提案的投票,同时与Leader进行数据交换(同步);
   Observer 直接为客户端服务但并不参与提案的投票,同时也与Leader进行数据交换(同步);
  图 2.1 ZK集群
DSC0001.png
2.2 QuorumPeer的基本设计
  图 2.2 QuorumPeer基本结构
DSC0002.png
  ZooKeeper对于每个节点QuorumPeer的设计相当的灵活,QuorumPeer主要包括四个组件:客户端请求接收器(ServerCnxnFactory)、数据引擎(ZKDatabase)、选举器(Election)、核心功能组件(Leader/Follower/Observer)。其中:
  ① ServerCnxnFactory负责维护与客户端的连接,接收客户端的请求并发送相应的响应;
   ZKDatabase负责存储/加载/查找数据,基于目录树结构的KV+操作日志+客户端Session;
   Election负责选举集群的一个Leader节点;
   Leader/Follower/Observer一个QuorumPeer节点应该完成的核心职责;
2.3 QuorumPeer工作流程
  图 2.3 QuorumPeer工作流程
DSC0003.png
  (1) Leader职责
  图 2.4 Leader工作流程
DSC0004.png
  Follower确认: 等待所有的Follower连接注册,若在规定的时间内收到合法的Follower注册数量,则确认成功;否则,确认失败。
  (2) Follower职责
  图 2.5 Follower职责
DSC0005.png
2.4 选举算法
  (1) LeaderElection选举算法
  图 2.6 LeaderElection
DSC0006.png
  选举线程由当前Server发起选举的线程担任,他主要的功能对投票结果进行统计,并选出推荐的Server。选举线程首先向所有Server发起一次询问(包括自己),被询问方,根据自己当前的状态作相应的回复,选举线程收到回复后,验证是否是自己发起的询问(验证Zxid 是否一致),然后获取对方的id(myid),并存储到当前询问对象列表中,最后获取对方提议的Leader 相关信息(id,zxid),并将这些 信息存储到当次选举的投票记录表中,当向所有Serve r
  都询问完以后,对统计结果进行筛选并进行统计,计算出当次询问后获胜的是哪一个Server,并将当前zxid最大的Server 设置为当前Server要推荐的Server(有可能是自己,也有可以是其它的Server,根据投票结果而定,但是每一个Server在第一次投票时都会投自己),如果此时获胜的Server获得n/2 + 1的Server票数,设置当前推荐的Leader为获胜的Server。根据获胜的Server相关信息设置自己的状态。每一个Server都重复以上流程直到选举出Leader。
  1) 初始化选票(第一张选票): 每个quorum节点一开始都投给自己;
  2) 收集选票: 使用UDP协议尽量收集所有quorum节点当前的选票(单线程/同步方式),超时设置200ms;
  3) 统计选票:
  ① 每个quorum节点的票数;
  ② 为自己产生一张新选票(zxid、myid均最大);
  4) 选举成功: 某一个quorum节点的票数超过半数;
  5) 更新选票: 在本轮选举失败的情况下,当前quorum节点会从收集的选票中选取合适的选票(zxid、myid均最大)作为自己下一轮选举的投票;
  异常问题的处理
  1) 选举过程中,Server的加入
  当一个Server启动时它都会发起一次选举,此时由选举线程发起相关流程,那么每个 Serve r都会获得当前zxi d最大的哪个Serve r是谁,如果当次最大的Server没有获得n/2+1 个票数,那么下一次投票时,他将向zxid最大的Server投票,重复以上流程,最后一定能选举出一个Leader。
  2) 选举过程中,Server的退出
  只要保证n/2+1个Server存活就没有任何问题,如果少于n/2+1个Server 存活就没办法选出Leader。
  3) 选举过程中,Leader死亡
  当选举出Leader以后,此时每个Server应该是什么状态(FLLOWING)都已经确定,此时由于Leader已经死亡我们就不管它,其它的Fllower按正常的流程继续下去,当完成这个流程以后,所有的Fllower都会向Leader发送Ping消息,如果无法ping通,就改变自己的状为(FLLOWING ==> LOOKING),发起新的一轮选举。
  4) 选举完成以后,Leader死亡,处理过程同上。
  5) 双主问题
  Leader的选举是保证只产生一个公认的Leader的,而且Follower重新选举与旧Leader恢复并退出基本上是同时发生的,当Follower无法ping通Leader是就认为Leader已经出问题开始重新选举,Leader收到Follower的ping没有达到半数以上则要退出Leader重新选举。
  (2) FastLeaderElection选举算法
  FastLeaderElection是标准的fast paxos的实现,它首先向所有Server提议自己要成为leader,当其它Server收到提议以后,解决 epoch 和 zxid 的冲突,并接受对方的提议,然后向对方发送接受提议完成的消息。
  FastLeaderElection算法通过异步的通信方式来收集其它节点的选票,同时在分析选票时又根据投票者的当前状态来作不同的处理,以加快Leader的选举进程。
  每个Server都一个接收线程池和一个发送线程池, 在没有发起选举时,这两个线程池处于阻塞状态,直到有消息到来时才解除阻塞并处理消息,同时每个Serve r都有一个选举线程(可以发起选举的线程担任)。
  1) 主动发起选举端(选举线程)的处理
  首先自己的 logicalclock加1,然后生成notification消息,并将消息放入发送队列中, 系统中配置有几个Server就生成几条消息,保证每个Server都能收到此消息,如果当前Server 的状态是LOOKING就一直循环检查接收队列是否有消息,如果有消息,根据消息中对方的状态进行相应的处理。
  2) 主动发送消息端(发送线程池)的处理
  将要发送的消息由Notification消息转换成ToSend消息,然后发送对方,并等待对方的回复。
  3) 被动接收消息端(接收线程池)的处理
  将收到的消息转换成Notification消息放入接收队列中,如果对方Server的epoch小于logicalclock则向其发送一个消息(让其更新epoch);如果对方Server处于Looking状态,自己则处于Following或Leading状态,则也发送一个消息(当前Leader已产生,让其尽快收敛)。
  图 2.7 FastElection
DSC0007.png
  (3) AuthFastLeaderElection选举算法
  AuthFastLeaderElection算法同FastLeaderElection算法基本一致,只是在消息中加入了认证信息,该算法在最新的Zookeeper中也建议弃用。
2.5 Zookeeper中的请求处理流程
  (1) Follower节点处理用户的读写请求
  图 2.8 Follower
DSC0008.png
  (2) Leader节点处理写请求
  图 2.9 Leader
DSC0009.png
  值得注意的是, Follower/Leader上的读操作时并行的,读写操作是串行的,当CommitRequestProcessor处理一个写请求时,会阻塞之后所有的读写请求。
  通信不可靠: 消息延迟、消息重复传递、消息丢失

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-110101-1-1.html 上篇帖子: zookeeper服务器端管理工具 下篇帖子: Solr 4.6 | Setting Up an External ZooKeeper Ensemble | upgrade solr to Solr4.6
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表