一致性算法的出现是为了解决一致性问题,一致性问题是指对于一组服务器(集群),给定一组操作,需要使用一种协议使得它们的结果最终达成一致,常用的一致性算法有 Paxos、Raft、ZAB 算法等。
如何构建一个既兼顾可用性又兼顾一致性的分布式系统,渐渐地就有了 Cap、Base 等分布式系统经典理论的出现。
CAP 理论:
- 一致性(Consistency)
- 可用性(Availability)
- 分区容错性(Partition tolerance)
对于一致性、可用性、分区容错性,一个分布式系统最多同时满足其中的两个。
关于一致性,与 A C I D ACID ACID 事物的一致性不同,这里强调的是多个副本之间的数据一致性。
关于可用性,表示在有限的时间内能否返回结果。
关于分区容错性,指的是在网络分区的情况下,仍然可以对外提供一致性和可用性的服务。
BASE 理论:
- 基本可用(Bascially Available)
- 软状态(Soft State)
- 最终一致性(Eventually Consistent)
关于基本可用,指允许损失部分可用性,例如响应时间上的损失,响应时间增加时间。
关于软状态,也称为弱状态,指允许系统在不同节点的数据副本之间进行数据同步的过程存在延时。
关于最终一致性,是一种特殊的弱一致性。指经过一段时间,系统最终能达到一致的状态,并不是实时保证系统数据的一致性。
Paxos 算法
Paxos 算法是一种非常重要的分布式一致性协议,该算法是 Leslie Lamport 提出,同时他也是 Latex 的发明者。
该算法追其本源是 “拜占庭将军问题” ,有三种参与角色,我们用 Proposer、Acceptor 和 Learner 来表示。
Paxos 过程
阶段一: 多个 Proposer 向多个 Acceptor 发送编号,注意的是, Acceptor 只会响应编号更大的 Proposer 请求,对于小的编号,则忽略。一般获得半数以上的 Acceptor 响应的 Proposer 会进入下一阶段(即多数派原则),由于并发,进入下一阶段的 Proposer 也会有多个。
阶段二: 选取主 Proposer,现在有多个 Proposer,假设 A 为其中一个,有三种情况,(1) 第一种是 A 在第一阶段已经被接受提议了,如果说 A 是第一个提出提议的人,那 A 就是主Proposer,以后只能由 A 提出的提议才能被 Acceptor 接受;(2)第二种是 A 在第一阶段得到 Acceptor 的回复中知道了谁是主 Proposer(假如说是 B),那以后只能是 B 提出的提议才有效。(3)第三种是 A 提出提议给 Acceptor,而 Acceptor 发现之前没有接受过 A 的提议,那么 Acceptor 会拒绝 A 的请求。
所以说,最后总会有一个 Proposer 会被响应接受,得到最终的提议。
阶段三: 让 Learner 获取到提议(backup),一般不让 Acceptor 发给所有的 Learner(网络通信次数太多了),所以通过 Acceptor 向主 Learner 发送提议,然后由主 Learner 同步给其他 Learner,但是为了防止主 Learner 发生单点故障,因此,主 Learner 也采用集合的方式。
ZAB 协议
基于 Paxos 的改进,ZAB 协议主要用于构建高可用的分布式数据主备系统,比如说 Zookeeper。
ZAB 协议的核心是高效处理会改变 Zookeeper 集群各个服务器数据状态的事物请求。
ZAB 协议原理
整个协议主要包括发现、同步、广播三个阶段。
- 发现: 要求 Zookeeper 集群必须选举出一个 Leader 进程,同时 Leader 会维护一个 Follower 可用客户端列表。将来客户端可以和这些 Follower节点进行通信。
- 同步: Leader 要负责将本身的数据与 Follower 完成同步,做到多副本存储。这样也是提现了CAP中的高可用和分区容错。Follower将队列中未处理完的请求消费完成后,写入本地事务日志中。
- 广播: Leader 可以接受客户端新的事务Proposal请求,将新的 Proposal 请求广播给所有的 Follower。
ZAB 与 Paxos 算法的联系与与区别
ZAB 协议并不是 Paxos算法的一个典型实现,我们来看看两者的联系。
- 两者都存在一个类似于 Leader 的角色,负责协调多个 Follower 进程的运行。
- Leader 进程都会等待超过半数的 Follower 作出正确的反馈后,才将一个提案提交。
- 在 ZAB 协议中,每个 Proposal 中都有一个 epoch 值,代表当前 Leader 的周期,在 Paxos 算法中,同样有这样一个东西,只不过换成了 Ballot 而已。
在 Paxos 算法中,一个新选举产生的主进程会进行两个阶段的工作,第一个阶段叫做读阶段——一个新的主进程会和所有其他进程进行通信,收集上一个主进程提出的提案,并把他们提交。第二阶段叫做写阶段——当前的主进程开始提出他自己的提案。而 ZAB 协议增加了一个同步阶段,在同步之前,ZAB 协议也有一个过程和 Paxos 算法中很类似,就是发现阶段。在同步中,新的 Leader 会确保半数机制,也就是确保有过半的 Follower 已经提交了之前 Leader 周期中的所有 Proposal。这个同步阶段他能有效保证 Leader 在新的周期提出 Proposal 前,所有的进程都完成对之前的 Proposal 的提交。在同步后,ZAB 一样的会执行和 Paxos 类似的写阶段。
总的来说, ZAB 协议和 Paxos 算法的本质区别是设计目标不太一样。ZAB 协议主要用于构建高可用的分布式数据主备系统,比如说 Zookeeper,而 Paxos 算法主要用于构建分布式的一致性状态机系统。