第一至第三部分的回顾

以下是上篇博客中所涵盖内容的回顾:

  1. 耐久性是我们使用共识系统的主要原因。
  2. 由于耐久性依赖具体的用例,我们将其抽象化为一个需求,使共识算法无需预设任何关于耐久性要求的假设。
  3. 我们从原始的共识系统属性开始(由Paxos定义),并对其进行了修改,使其能够应用在实际场景中:我们将“收敛到单个值”的系统更改为“接受一系列请求”的系统。
  4. 我们集中于单一领导的共识系统范围。
  5. 我们定义了一组新规则,这些规则与耐久性无关。系统若符合这些规则,即可满足共识系统的要求。具体而言,我们排除了部分算法核心构建基础(例如以前被广泛采用的大多数仲裁规则)。

共识算法的应用场景

如果我们不需要考虑多数仲裁(majority quorum),那么我们可以灵活地部署所需数量的节点。我们可以指定其中任意一部分节点作为领导节点,并可根据需求自由决策耐久性等级,而无需受上述两个决策的限制。这正是许多用户利用 Vitess 的方式。以下用例是基于实际生产工作负载的松散衍生:

  1. 我们在多个数据中心内部署了大量副本节点,其中有15个领导节点分布在三个数据中心。我们预计不会有两个节点同时宕机。网络分区可能发生,但仅限于两个数据中心之间;数据中心不会被完全隔离。数据中心也可能因计划维护而关闭。
  2. 我们部署了四个区域,每个区域内有一个节点。任何节点都可能故障;区域可能无法提前通知就发生故障。分区可能发生在任意两个区域之间。
  3. 我们有六个节点分布在三个区域中。任何节点都可能故障;区域可能无法提前通知就关闭。分区可能发生在任意两个区域之间。
  4. 我们有两个地区,每个地区有两个区域。我们预计不会超过一个区域宕机。如果一个地区因维护需要关闭,我们希望主动将写操作切换到另一个地区。

我尚未看到有人提出超过两个节点的耐久性要求。但这可能是由于 MySQL 的半同步行为引发的角落情况难以处理。另一方面,这些设置已经很好地满足了用户需求。那么,何必变得更加保守?

这些配置对于基于多数派的共识系统来说并不适应。更重要的是,这种灵活性将鼓励用户尝试更具创造性的新组合,并有效实现更好的权衡。

灵活共识的思考方式

上一节中的配置看起来杂乱无章。如何设计一个系统可以满足所有这些场景,并确保未来不会被新的需求所束缚?

幸好,有一种方法可以说明为何如此灵活。这是因为两个协作算法(请求和选举)共享着相同的耐久性视图,但在其他方面可以独立运行。

例如,考虑一个五节点系统。如果用户不希望在任何时间有超过一个节点故障,那么他们可以指定耐久性要求为“两节点”。

  • 在请求方面:作为领导节点,当数据到达另外一个节点时,耐久性已满足,我们可以向客户端返回成功响应。
  • 在选举方面:若发生故障,我们知道最多只有一个节点会不可用。这意味着仍有四个节点可达,其中至少一个节点拥有所有成功请求的数据。选举过程依然可以传播数据并在选出新领导后继续接受新的请求。

换言之,单一耐久性约束决定了系统的两方面行为;如果我们能够找到一种正式的方法来描述这些需求,那么请求必须满足这些需求,而选举流程也必须满足这些需求且覆盖到足够多的节点进行交集。

例如,如果耐久性要求是 5个节点中的2个,那么选举算法需要达到 5个节点中的4个才能与耐久性标准重合。在多数仲裁情况下,这两个条件均为 5个节点中的3个。但是我们的通用化可以适用于任意属性组合。

最坏情境

在上述五节点配置中,如果两个节点宕机,则超过了容错极限。此时仅能访问三个节点。如果我们无法得知另外两个节点的状态,则必须假设最坏情境:耐久的请求可能已被两个不可访问的节点接受。这会导致选举流程进入停滞。

当遇到这种情况时,系统必须允许妥协:放弃这两个节点并继续运行。否则,失去可用性可能比潜在的数据丢失代价更高。

实际权衡

两节点的耐久性要求并不意味着系统将停滞或丢失数据。这需基于以下特定的故障序列:

  1. 领导节点接受了一个请求。
  2. 领导节点尝试将请求发送至多个接收节点。
  3. 只有一个接收节点收到并确认该请求。
  4. 领导节点向客户端返回成功。
  5. 领导节点和接收节点均宕机。

这种故障可以在领导节点和接收节点被网络分区在集群之外的场景下发生。通过要求确认节点分布在网络边界之间,可以缓解这种失败。

例如,在一个跨单元的副本节点收到确认后,该单元的主节点宕机和另一单元的领导节点同时故障的概率非常低。这种故障模式罕见,对于许多用户来说,这种风险是可以接受的。

数量级分布

在共识系统中,完成请求是最常见的操作。相比之下,领导选举通常只在以下情况发生:节点因故障或维护需要关闭。

甚至在 Kubernetes 这样动态云环境下,一个集群一天允许超过一次选举也会令人惊讶;而与此同时,此类系统可能每秒处理数百个请求。这就导致了请求处理和领导选举之间的数量级差异。

因此,我们必须尽一切努力优化处理请求的部分,而允许选举过程更为精细和缓慢。这也是我们倾向于将耐久性设定为最低要求的原因。增加确认节点的数量可能会对性能(尤其是尾延迟)产生负面影响。

例如,在 YouTube 中,尽管仲裁规模较大,仅通过一个副本确认就是完成请求的充分条件。另一方面,选举过程则需要追踪所有可能确认了最后一次事务的节点。这是一个有意识的权衡,以避免对确认节点进行彻底的搜索。

下一篇文章

在下一篇博客中,我们将有一个短暂的转折。Shlomi Noach 将讨论某些方法如何与 MySQL 和半同步复制结合。随后,我们将继续推进这些算法的实现细节。



共识算法的规模化应用:第三部分 – 用例插图

关注公众号:程序新视界,一个让你软实力、硬技术同步提升的平台

除非注明,否则均为程序新视界原创文章,转载必须以链接形式标明本文链接

本文链接:http://www.choupangxia.com/2025/05/19/consensus-algorithms-3/