2021-04-18

再谈 Paxos 和 Raft

Views: 5120 | Add Comments

我之前写过一些谈 Paxos 的文章[1][2], 特别是将 Paxos[3] 和 Raft[4] 进行了对比. 由于我更多的是站在工程实现的角度考虑两种技术的优缺点, 所以造成了不少读者感受到我有非常强的"贬 Paxos, 赞 Raft"的倾向. 不可否认, 从工程实现的角度, Paxos 的指导意义非常抽象且不直接, 所以我们必须""亲 Raft 远 Paxos".

实际上, 许多人认为 PaxosRaft 不是同一层面的东西. 另一方面, 某种角度看他们又同一层面的东西, 当然要做比较. 所以, 我们在讨论这两种技术时, 要注意所设的场景和条件, 否则极易让人误会.

有一个说法比较经典:

Mike Burrows, inventor of the Chubby service at Google, says that “there is only one consensus protocol, and that’s Paxos” - all other approaches are just broken versions of Paxos. - [source]

翻译便是:

Google Chubby 的发明者 Mike Burrows, 说过"世上只有一种共识协议, 那就是 Paxos" - 其它的全是 Paxos 的残缺版本. - [来源]

这个说法常常引申之后用来对比 Paxos 和 Raft, 然后把 Raft 归结为所谓的"残缺版本", 以获得无知而且猥琐的心理满足感. 根据来源网址, 似乎 Mike 只说 Paxos 是唯一一种共识协议, 后面那句轻浮的, 狡黠的, 稚儿指点江山似的说法 - 其它的全是 Paxos 的残缺版本 - 估计是文章的作者加上的, 并非 Mike 本话.

我个人也认为 Paxos 是唯一的共识协议(算法), Raft 虽然自称是共识协议, 但我认为 Raft 包含的内容比 Paxos 要广泛太多, Raft 应该归类为分布式领域的一种工程实践总结. 如果仅从共识协议的层面看, 两者不应该进行比较.

仔细研读 Paxos 共识流程, 可以理解为两步:

  1. 所有节点交换当前状态, 分配递增的操作序号(流水号)
  2. 将旧状态(如有)或者新状态(如无旧状态), 复制给所有节点

操作序号用来决定成员内部状态的新旧, Quorum(一般是多数派)用来决定整个系统(所有节点的全体)对外展示哪个状态(共识). 要注意, 理论上, 因为外部观察者不是上帝, 所以不应该看到成员内部的状态, 外部观察者看到的是所有成员作为一个整体所展示的外部状态(共识). 所以, 各成员的内部状态未必相同的(一致的), 但是, 对外展示的状态一定是相同的(一致的).

Basic Paxos 所描述两阶段, 并没有区分工程上所理解的读和写, 所以, 在工程实践总是造成疑惑. 从工程实践的角度看 Paxos, 无论读写, 都要完整地执行两阶段, 也即必须总是分配新序号和复制状态. 显然, 这种约束完全破坏了工程实践, 读操作为什么要分配序号? 我又不是要写数据. 还有, 我只是访问某个节点读数据, 为什么所有节点要复制数据?

工程实践上, Paxos 是反直觉的, 而且非常的没有优化(慢, 性能差, 低效). 所谓的两阶段, 根本就不允许修改状态, 因为达成共识之后, 就不能再改变状态, 这在工程实践上也是无法接受的.

另外, 如果节点的粒度是一个数据库的话, 那么所谓的状态就是整个数据库, 几百GB的数据, 每一次外部操作都要在各节点之间不断地复制状态(几百GB的数据), 工程实践上也无法接受.

总而言之, Basic Paxos 虽然是唯一正确的共识协议(共识算法), 但它确实仅仅是一个共识协议, 没有工程实践上的直接意义. 所有的工程实践必须对 Paxos 进行优化, 最终, 大家都优化(实现)成 Raft 的样子.

Paxos 进一步引入了 Multi Paxos, 算是一种初级的日志复制状态机(Raft 重点推广的核心概念), 正如 Basic Paxos, 依然是正确的理论, 但是没有直接的实践指导意义, 例如, 缺少一致性约束方面的内容.

我们来看看 Raft 是如何对前面提到的几点工程实践上无法接受 Paxos 的点进行改进的:

1, 不能修改状态

Raft 总结了日志复制状态机, 所有节点对操作序列(日志)达成共识, 然后按顺序重放每一个操作. 每一个操作只修改子状态(例如数据库中某一表的某一行), 最终所有节点的内部状态(整个 DB 级别)达成一致(相同). 因为操作序列可以不断地增加, 所以, 整个系统的状态也就可以持续修改.

2, 复制整个巨大的状态

日志复制状态机模型, 只需要复制操作日志, 可以增量复制, 不需要每一次都复制整个非常巨大的状态.

3, 读操作也要写数据

Raft 引入了明确的 Leader, Leader 掌握了所有节点的状态, 单独决定整个系统应该对外展示何种状态, 所以不进行所谓的两阶段分配序号, 复制状态这些 IO 读写操作.

总结

不可否认, Paxos 是唯一正确的共识协议(共识算法), 但是, Raft 绝不仅仅是一个共识算法, 而是一套完善的工程实践, 是对过去工程实践的理论总结, 也是对未来的工程实践的正确指导.

总结过去, 指导未来, Raft 不是唯一正确的理论, 但是, 目前来看, 确是非常重要的理论. 相信 Raft 的生命力还会长期持续强劲.

最后, 在工程实践的层面, 希望大家正确理性地看待 Paxos, 千万不可陷入小孩本能喜欢吃糖一样的生理本能陷阱, 对 Paxos 抱有低级本能的生理独好, 忽略甚至排斥更有益更上层(高级)的东西.

相关资料

Related posts:

  1. Paxos vs Raft 的争论
  2. Paxos 和 Raft 的结构差异
  3. Paxos 与分布式强一致性
  4. 为什么 Leader Based 的分布式协议 Raft 是更好的
  5. 为什么极少有开源的Paxos库?
Posted by ideawu at 2021-04-18 11:59:48 Tags: ,

Leave a Comment