Multi-paxos算法

问题的描述

  • 原始的Paxos算法(Basic Paxos)中决议的形成至少需要两次网络来回(RTT)。如果 Proposer数量很多。会导致并发冲突很高,可能需要更多的网络来回才能选定一个值。极端情况下甚至可能形成活锁。
  • 实际应用中很多时候需要连续对多个值达成一致。使用Basic Paxos需要针对每一个要确定的值,独立运行一次Paxos算法实例(Instance),形成决议。我们保证仅当Instance i的值被确定后,方可进行i+1的Paxos算法,这样我们就保证了Instance的有序性。这样的延迟很高。Multi-Paxos正是为解决此问题而提出。
  • 通过Multi-Paxos可以连续选定多个值,而且这些值的顺序在各个节点完全一致。

算法的概述

  • Multi-paxos算法的核心在于Leader的引入。
  • 可以通过执行一次Basic Paxos,在所有的Proposer中选举一个leader。选出Leader之后只能由Leader充当 Proposer。其他机器收到写请求,都把写请求转发给 Leader;或者让客户端把写请求都发给 Leader。
  • 在系统中仅有一个Leader进行Value提交的情况下。由于没有Proposer竞争,因此解决了活锁问题。并且,因为Prepare阶段不会存在冲突,后面的proposal可以选用同一个proposal id,并跳过Prepare阶段,直接执行Accept操作。从而将两阶段变为一阶段,提高效率。
  • 为了区分连续提交的多个实例,每个实例使用一个Instance ID标识,Instance ID由Leader本地递增生成即可。

leader的选举

可以通过执行一次Basic Paxos,从所有的Proposer节点中选举出一个Leader。leader当选后,可以通过了lease机制维持自己的leader身份,使得其它proposal不再发起提案
,这样就进入了leader任期。

leader的异常

Leader在任期内,需要定期给各个节点发送心跳,证明leader还活着(正常工作)。如果一个节点在超时时间内仍然没有收到leader的心跳,它会尝试发起选主流程。

  • 进程crash(OS crash)

Leader进程crash和Os crash类似,只要重启时间大于心跳超时时间,所有的节点先后都会出现超时,进入选主流程。

  • 节点网络异常(节点所在网络分区)

Leader网络异常同样会导致其它节点收不到心跳,但有可能leader是活着的,只不过发生了网络抖动,因此心跳超时不能设置的太短,否则容易因为网络抖动造成频繁选主。另外一种情况是,节点所在的IDC发生了分区,则同一个IDC的节点相互还可以通信,如果IDC中节点能构成多数派,则仍能从多数派中诞生leader。如果不能,比如总共4个节点,两个IDC,发生分区后会发现任何一个IDC都无法达成多数派,导致无法选出主的问题。因此一般Paxos节点数都是奇数个,而且在部署节点时,IDC节点的分布也要考虑。因此一般Paxos节点数都是奇数个,而且在部署节点时,IDC节点的分布也要考虑。

新主的选举

由于Paxos中并没有限制,任何节点都可以参与选主并最终成为leader,这让新选出的leader可能没有某些已经达成一致的instance value,因此在真正提供服务前,还存在一个获取所有选定的instance value的恢复过程。

新leader向所有成员发送查询最大instance id的请求,收到majority的响应后,选择最大的instance id作为恢复的结束点。这里取majority的意义在于恢复结束点包含任何的majority达成一致的日志。

拿到instance id后,对于每个instance都运行一次paxos:如果instance之前已经达成一致了,那么再次运行paxos不影响结果。如果instance之前并没有达成一致,当返回的majority中包含 该instance时,它会被选出,在accept阶段提交。如果返回的majority不包含该instance,就不会被选出。

恢复的优化

可以看出,如果instance非常多,每次重启后都要对每个instance做一次paxos,那么恢复时间可想而知。而对于已经达成一致的instance,paxos结果是确定的,再做一次就是不必要的了。

paxos协议中,只有leader知道哪些instance达成了一致,acceptor不知道,那么很容易想到的一个优化就是proposer将已经达成一致的instance 信息告诉其他acceptor, acceptor该confirm信息其持久化到本地。后续重启的时候,扫描本地只要发现对应的confirm信息就知道这个instance已经达成多数派,不需要重新使用paxos进行确认了。

出于性能的考虑,confirm信息往往是延迟的成批写出去,因此仍然会出现部分instance已经形成多数派备份,但是acceptor中没有对应的confirm信息的情况,对于这些instance,需要在恢复过程中进行重确认。

读写服务

Multi-Paxos协议中只有leader确保包含了所有已经已经持久化的日志,当然本地已经持久化的日志不一定达成了多数派,因此对于没有confirm的日志,需要再进行一次投票,然后将最新的结果返回给client。而非leader节点不一定有所有最新的数据,需要通过leader确认,所以一般工程实现中,所有的读写服务都由leader提供。

下一节:ZooKeeper简介

你可能感兴趣的:(Multi-paxos算法)