Paxos那些事儿

为何prepare请求要过半返回才算成功?

  • 可终止性:一旦有过半节点的为同一个状态,则集群的状态确定,以后无法改变;
  • 获取Accept请求锁:集群任何时刻,Accept只能接受一个版本号,即最近成功请求prepare的版本号;

为何要使用最新的版本号?

  • Paxos的约定:分歧状态下选取最新的提案广播
  • Acceptor的目的就是获取集群最新状态
  • Paxos选举是一个过程,从集群的多种状态最终衍变到唯一状态,后者认同前者

Paxos选举的原子性?

  • Prepare、Accept通过序号锁定一次选举:
    • 串行执行:P1————>o|P2————>o|A1- - - - ->o|A2————>o

Paxos选举的生命周期

  • 如果出现大于自己之前收到的序号,说明选举仍然在继续
  • 历史终究是历史,历史不能改变,能改变的只有未来

Paxos选举过程的中关键节点

  • 非空未过半
  • 非空过半
  • 相同状态未过半
  • 相同状态过半————结束

Paxos、ZAB、Raft三者关系

  • 个人认为Paxos与ZAB、Raft没有什么关系,因为ZAB、Raft是有Leader的角色,提案广播是基于顺序的,过程中某一提案是否最终提交可以依赖于下一次广播;而Paxos理论上任何节点都可以发起提案,而每一次选举是独立的。
  • 如果硬要说有什么相似之处,那么ZAB选Leader的过程与Paxos是非常相近的,区别就在于约定不同,Paxos的前提是选取最新提案而不关心提案的值,而ZAB选择提案是根据提案的值来确定,因此Paxos需要一个版本号,而ZAB不需要,有人会说ZAB也有版本号的东东,其实在Paxos的世界里那个不是提案的版本号,是提案的值。
  • Raft选Learder的做法似乎与Paxos和ZAB都不同,选Leader不关心版本号,也不关心提案的值,每个Raft节点都会发起选举请求,为了避免冲突,每个节点sleep一个随机值,谁先获取过半数响应谁就是Leader;这么选Leader后log的index不一样怎么办?很简单,选完Leader后由Leader进行同步,这有点意思。不过Raft在多节点集群以及较差网络环境下进行Leader选举似乎会比较困难了。

ZAB、Raft协议的可终止性实现

  • Paxos基于读写串行操作,终止性保证容易理解。对于ZAB和Raft,虽然Leader选举算法不同,但是关于可终止性实现上有相似之处。每个节点刚自认为被选为Leader之后,会给它投票的过半集合发同步请求,如果同样收到了过半集合的Ack,,则Leader取得了其他节点的认可真正成为了Leader,选举结束了。

那些事儿

  • 相同状态未过半时的集群状态
    • 实际的状态
    • “我眼中的状态”
  • 最大提交原则:冲突状态时某次提案获得Accept响应的节点越多,本次提案的值越有可能成为过半数节点的值,即集群最终值。