回忆一下 paxos 算法: 多个结点对于一个事情达成共识。共识只有一个且不会被修改。限定在非拜占庭场景。 Simple Paxos 提出了一个做法。算法采用两阶段,第一阶段结点提出提议争取其它结点的承诺,如果提出者的提议号比自己收到的提议大,就承诺在二阶段不通过小于提议号的提议,并返回如果已有提议内容。如果结点争取到大多数的结点承诺,就发起二阶段流程。如果不违法自己的承诺,各结点就通过提议。在大多数结点通过提议的时候,这个提议就被选定了,成为了共识,之后再也不会变化。
论文中的描述是按照这样的逻辑来描述的:如果满足条件 A 的情况下 B 成立。 这个时候我们加强 A 的条件, B 当然也会成立。我们也可以用反证法来证明满足约束的条件下共识一定不会有不同的值。
业界主流的实现是按照上述流程来实现,也有一个更神奇优雅当然也更难懂的实现。完全异步的基于不同结点的视图信息同步来推进算法流程的算法,具体可以参考微信开源的 KVStore Certain。
上述算法是确定一个共识,在工业界实际使用的时候,其实是要确定连续的多个共识,这样才能维护出一个大家都完全一致的日志流,状态机通过回放日志流得到一致的状态。如果每个日志都用二阶段,算法性能明显很低,所以大家想到了很巧妙的解法:一种是先用共识来选主,来跳过第一阶段。还有一种是在前一个日志中隐藏信息,如果是前一个日志中的结点可以跳过第一阶段,大家默认已经承诺了它的提议序列号。另外还有成员变更的问题,有一种作法就是写入一个特殊的日志,将新成员列表写到日志内容中,后续成员以日志内容为准。
paxos 算法相对 raft 算法的好处是逻辑上更优雅简单细节少,没有选主过程所以也没有主挂掉时候的超时时间内不可用问题。缺点就是只是个算法,没有具体的工程实现细节,一些场景下没有 raft 性能好。