分布式一致性,简单的说就是在一个或多个进程提议了一个值后,使系统中所有进程对这个值达成一致。

分布式一致性 - 图1
为了就某个值达成一致,每个进程都可以提出自己的提议,最终通过分布式一致性算法,所有正确运行的进程学习到相同的值。
工业界对分布式一致性的应用,都是为了构建多副本状态机模型(Replicated State Machine),实现高可用和强一致
分布式一致性 - 图2
分布式一致性使多台机器具有相同的状态,运行相同的确定性状态机,在少数机器故障时整体仍能正常工作。

分布式一致性 - 图3

Paxos

Paxos达成一个决议至少需要两个阶段(Prepare阶段和Accept阶段)。

分布式一致性 - 图4
Prepare阶段的作用:

  • 争取提议权,争取到了提议权才能在Accept阶段发起提议,否则需要重新争取。
  • 学习之前已经提议的值。

Accept阶段使提议形成多数派,提议一旦形成多数派则决议达成,可以开始学习达成的决议。Accept阶段若被拒绝需要重新走Prepare阶段。
缺点: 达成一次决议至少需要两次网络来回并发情况下可能需要更多极端情况下甚至可能形成活锁,效率低下

Multi-Paxos


分布式一致性 - 图5
Multi-Paxos选举一个Leader,提议由Leader发起,没有竞争,解决了活锁问题。提议都由Leader发起的情况下,Prepare阶段可以跳过,将两阶段变为一阶段,提高效率。Multi-Paxos并不假设唯一**Leader**,它允许多Leader并发提议,不影响安全性,极端情况下退化为Basic Paxos。

Multi-Paxos与Basic Paxos的区别并不在于Multi(Basic Paxos也可以Multi),只是在同一Proposer连续提议时可以优化跳过Prepare直接进入Accept阶段,仅此而已。

Raft

不同于Paxos直接从分布式一致性问题出发推导出来,Raft则是从多副本状态机的角度提出,使用更强的假设来减少需要考虑的状态,使之变的易于理解和实现。

Raft Multi-Paxos
Leader Proposer
Term Proposal ID
Log Entry Proposal
Log Index Instance ID
Leader选举 Prepare 阶段
日志复制 Accept 阶段

Raft假设系统在任意时刻最多只有一个**Leader**提议只能由**Leader**发出(强Leader),否则会影响正确性;而Multi-Paxos虽然也选举Leader,但只是为了提高效率,并不限制提议只能由Leader发出(弱Leader)。

强Leader在工程中一般使用Leader LeaseLeader Stickiness来保证:

  • Leader Lease:上一任Leader的Lease过期后,随机等待一段时间再发起Leader选举,保证新旧Leader的Lease不重叠。
  • Leader Stickiness:Leader Lease未过期的Follower拒绝新的Leader选举请求。

Raft限制具有最新已提交的日志的节点才有资格成为Leader,Multi-Paxos无此限制。

Raft在确认一条日志之前会检查日志连续性,若检查到日志不连续会拒绝此日志保证日志连续性,Multi-Paxos不做此检查,允许日志中有空洞。

EPaxos

EPaxos是一个Leaderless的一致性算法,任意副本均可提交日志,通常情况下,一次日志提交需要一次或两次网络来回。

EPaxos无Leader选举开销,一个副本不可用可立即访问其他副本,具有更高的可用性。各副本负载均衡,无Leader瓶颈,具有更高的吞吐量。客户端可选择最近的副本提供服务。

不同于Paxos和Raft,事先对所有Instance编号排序,然后再对每个Instance的值达成一致。
EPaxos不事先规定Instance的顺序,而是在运行时动态决定各Instance之间的顺序。EPaxos不仅对每个Instance的值达成一致,还对Instance之间的相对顺序达成一致**。EPaxos将不同Instance之间的相对顺序也做为一致性问题,在各个副本之间达成一致,因此各个副本可并发地在各自的Instance中发起提议,在这些Instance的值和相对顺序达成一致后,再对它们按照相对顺序重新排序,最后按顺序应用到状态机。

EPaxos引入日志冲突的概念(与Parallel Raft类似,与并发冲突不是一个概念),若两条日志之间没有冲突(例如访问不同的key),则它们的相对顺序无关紧要,因此EPaxos只处理有冲突的日志之间的相对顺序

若并发提议的日志之间没有冲突,EPaxos只需要运行PreAccept阶段即可提交(Fast Path),否则需要运行Accept阶段才能提交(Slow Path)。

PreAccept阶段尝试将日志以及与其它日志之间的相对顺序达成一致,同时维护该日志与其它日志之间的冲突关系,如果运行完PreAccept阶段,没有发现该日志与其它并发提议的日志之间有冲突,则该日志以及与其它日志之间的相对顺序已经达成一致,直接发送异步的Commit消息提交;否则如果发现该日志与其它并发提议的日志之间有冲突,则日志之间的相对顺序还未达成一致,需要运行Accept阶段将冲突依赖关系达成多数派,再发送Commit消息提交。

相关链接

  1. 一文总结:分布式一致性技术是如何演进的?