本文主要是介绍从Paxos到Zookeeper(三),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
前言
前面已经介绍了Paxos,这章开始学习Paxos在Zookeeper中的应用,主要介绍ZAB协议,Chubby和Hypertable估计也接触不到,这里先简单介绍下Zookeeper。
1、Zookeeper简介
相信大部分从事分布式开发项目的人都有过使用经验,其设计目标是将那些复杂且容易出错的分布式服务封装起来,构成一个高效可靠的原语集,并以一系列简单易用的接口提供给用户使用,分布式应用程序可以基于它实现诸如数据发布/订阅、负载均衡、命名服务、分布式协调/通知、集群管理、Master选举、分布式锁和分布式队列等功能,可以保证如下分布式一致性:顺序一致性、原子性、单一视图、可靠性以及实时性等特点,其设计目标包括以下四点(一句话总结):
- 简单的数据模型:通过一个共享的、树型结构的名字空间来进行相互协调;
- 可以构建集群:集群中每台机器之间保持通信,当超过一半节点正常工作时,则能正常对外提供服务;
- 顺序访问:通过一个递增的全局唯一的编号,来反映所有事务操作的先后顺序;
- 高性能:将全量数据存储在内存中,并直接服务于客户端的所有非事务请求;
这里多讲一点:为什么选择Zookeeper?在第一章中讲过,随着分布式架构的出现,分布式系统的最大痛点--数据一致性问题也随之出现,然后直到现在,除了Zookeeper,还没有一个稳定成熟且被大规模应用的解决方案,无论从易用性、性能还是稳定性上来说,Zookeeper都是不二之选。
2、ZAB协议
Zookeeper并没有完全采用Paxos,采用的是Zookeeper Atomic Broadcast(ZAB)协议作为其数据一致性的核心算法,ZAB协议是为分布式协调服务Zookeeper专门设计的一种支持奔溃恢复的原子广播协议。
2.1 协议介绍
ZAB采用主备架构,保证同一时刻集群中只能够有一个主进程来广播服务器的状态变更,因此能够很好地处理客户端大量的并发请求;另一方面,考虑到在分布式环境中,顺序执行的一些状态变更其前后会存在一定的依赖关系,有些状态变更必须依赖于比它早生成的那些状态变更,这样的依赖关系也对ZAB协议提出了一个要求:ZAB协议必须能够保证一个全局的变更序列被顺序应用,也就是说,ZAB协议需要保证如果一个状态变更已经被处理了,那么所有其依赖状态变更都应该被提前处理掉了,,另外ZAB协议还需要能够做到主进程异常时,依旧能够正常工作。
在ZAB中,所有的事务请求必须由一个全局唯一的服务器来协调处理,这样的服务器被称作Leader服务器,而余下的称作Follower服务器,Leader将一个客户端事务请求转换为一个事务Proposal(提议),并将该Proposal分发给集群中所有的Follower服务器,然后等待半数以上Follower正常反馈后,再发送Commit消息,要求将前一个Proposal进行提交。
2.2 两种模式
ZAB包括奔溃恢复和消息广播两种模式,当Leader服务器出现网络中断、奔溃或重启等异常情况时,ZAB就会进入恢复模式选举新的Leader,当集群中已经有过半的机器与该Leader服务器完成了数据同步后,ZAB就会退出恢复模式;当集群中有一半节点正常可用时,那么集群就会进入消息广播模式,这里值得注意的是,当一台新的服务器加入集群后,它应该自觉进入数据恢复模式,然后再参与到消息广播模式中去,该节点在进入数据恢复模式后,第一件事应该是找到Leader节点,并与其进行数据同步,第二章中已经介绍过,Leader服务器是唯一的,因此,所有的事务处理应该交给该节点唯一处理,而非Leader节点收到请求后,首先也应该转发给Leader节点。
消息广播
ZAB协议的消息广播过程使用的是一个原子广播协议,类似于一个二阶段提交过程,leader根据客户端的事务请求生成proposal,并发送给其余所有的机器,然后再分别收集各自的选票,半数通过以后再进行事务提交,ZAB相对于Paxos在二阶段提交中移除了中断逻辑,这就意味着,不需要等到所有节点都完成反馈,就会开始进行事务提交(即超过半数就进行二阶段提交),可以想象,如果此时集群奔溃,就会带来数据不一致的问题,因此ZAB新增了奔溃恢复模式来保证数据一致性。消息广播协议严格遵循FIFO特性的TCP协议以保证消息接收与发送的顺序性,在事务广播之前会为proposal分配一个全局单调递增的ZXID,按照ZXID的先后顺序来处理。
奔溃恢复
前面已经提到奔溃可能带来的数据不一致的影响,一旦leader发生奔溃(因为leader只有一个),或者leader与过半的节点断联,便需要重新选举leader,ZAB协议需要保证快速的选举出新的leader,同时还需要让集群中的其他节点能够快速感知到新的leader已经产生。通过介绍可能出现的两个数据不一致的隐患来介绍ZAB的解决方案。
- ZAB需要保证Leader服务器上提交的时候最终被所有节点提交:假设一个事务在Leader上提交了,并且已经得到了过半Follower的反馈,但是在Leader将该事务的Commit请求发送给所有节点之前宕机了,这时,必须确保该事务被所有Follower节点提交成功,否则将出现不一致的情况;
- ZAB协议需要确保丢弃那些只在Leader服务器上被提出的事务:如果在奔溃恢复过程中出现一个需要被丢弃的提案,那么在奔溃恢复结束后需要跳过该事务Proposal,比如Leader A在提交一个Proposal P1后就奔溃了,当奔溃恢复后,ZAB需要保证P1被丢弃;
以上两点要求ZAB必须能够确保提交已经被提交的事务,同时丢弃已经被跳过的事务。因此ZAB的Leader选举算法要求选出集群拥有最大ZXID的节点,这样就能保证这个新选举出来的Leader一定具有所有已经提交的提案,在选举完新的Leader后就要进行数据同步,保证所有的Follower节点与Leader节点达成数据一致后才能进行接下来的事务处理。
总结
ZAB作为Paxos的工业应用,与Paxos有以下联系与区别:
联系:
- 两者都存在Leader节点,由其协调多个Follower进程的运行;
- Leader进程都会等待超过半数的Follower做出正确反馈后才会进行提案的提交;
- 在ZAB协议和Paxos中都包含一个值来记录当前Leader的周期,在ZAB中这个值叫epoch,而在Paxos中这个值叫Ballot;
区别:
- Paxos包括读阶段和写阶段,ZAB在Paxos的基础上增加了一个同步阶段;
- 在同步阶段,ZAB会保证过半的Follower已经提交了之前Leader周期的所有事务;
总的来讲,ZAB和Paxos的本质区别在于两者的设计目标不大一样,ZAB旨在构建一个高可用的分布式数据主备系统,而Paxos的目标则是构建一个分布式的一致性状态机系统。
这篇关于从Paxos到Zookeeper(三)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!