要回答这个问题,先要了解以下几个问题
Paxos是一个Consensus Algorithm。国内很多文章将Consensus翻译为“一致性”,从中文理解上没有什么问题,口语中,我们也会常把“共识”和“一致性”交替使用。例如,“去云南旅游达成共识了”和“去云南旅游达成一致了”,这两句表达的是同一个意思。但是在计算机的分布式环境中,这两个词略有差别。
一致,是指各个副本之间的数据100%保持相同的状态,例如CAP中的C,就是指100%的一致性,CA之间权衡,指每个成员的数据都是一致的。C和A之间权衡,就是一个调节(0~100%)强度的哲学问题。详细可以参考:
共识,是指从外部观察者(客户端)看来,系统内部的数据是保持一致的,无论访问哪个副本都能获得相同的数据,而系统内部的真实情况,可能不是100%保持一致的。所以Paxos算法翻译为“共识算法”更为合适。
一个共识算法,除了保证算法的正确性之外,容错性也是必不可少的,Paxos同样也不例外。为了实现高容错性,Paxos允许少数的成员发生故障,在抉择一个提案是否达成共识时,只需要多数派成员支持即可。
Paxos算法分为两个阶段,Prepare阶段和Accept阶段。,Prepare阶段用于争取本轮发起协商的所有权,和获取上一轮协商可能达成共识的提案。所以我们也可以认为Prepare阶段认为是读阶段,Accept阶段认为是写阶段。
为了保证已达成共识的提案不再改变,当读阶段获取到有可能达成共识的提案后,写阶段只能用该提案发起协商。而两个互不相干的阶段,能够交换信息,必须要有通信的媒介,这个通信的媒介源于“多数派”。因为“多数派思想”能够保证任何两个多数派集合相交,那么这个相交的副本就是通信的媒介,我们只需要控制相交的副本所以支持提案的规则(当然,所有副本都可能是相交的副本),就能让读阶段获取到上一轮写阶段可能达成共识的提案,延续这个可能达成共识的提案,在本轮也只能提出该提案,那么就能保证已达成共识的提案不再改变。
Paxos只需要多数派支持即可,因此每个成员之间的数据是不一致的,但一定存在一个多数派拥有一致的数据。
因此Paxos处理读请求,通常需要再运行一轮Paxos,通过Prepare阶段获取是否有多数派对某个提案达成共识了。
当然每次读请求都运行一轮Paxos,这个效率是非常慢的,所以在行业内也有一个优化方案,例如增加一轮confirm请求,为已达成共识的提案记录confirm日志。
Leaner如何获取达成共识的提案?通常有两个方案,最常用的是第2种,第1种效率不高,且Learner要求一定的计算能力。