领导选举过程是共识过程当中较少使用的一部分。然而,这一部分也是更为复杂的一环。因此,我们将首先深入探讨这一部分。

第一至第三部分回顾

  • 持久性是我们需要采用共识系统的主要原因。
  • 由于持久性依赖于具体的使用场景,我们将其抽象为一种要求,并让共识算法对持久性要求保持无假设的态度。
  • 我们从Paxos定义的原始共识系统属性出发,并对其做了修改,使其在实际场景中可用。我们将系统目标从聚合单一值转变为接受一系列请求。
  • 我们把范围缩小到单领导者系统
  • 我们提出了一套新的规则,这些规则与持久性无关。这些规则的核心论点是,遵循这些规则的系统能够满足共识系统的需求。尤其是,我们排除了某些曾在共识算法中作为核心构件的需求,例如多数派投票机制。
  • 我们研究了多个实际场景,并发现采用简单的多数派投票方法在一些情况下难以奏效。而灵活的共识系统能够更好地适应这些用例。

过度耦合多个关注点

传统算法如Paxos和Raft试图同时解决多个问题。这种方法虽巧妙,但其实现过于僵硬,无法对算法中的某一部分进行修改而不影响其他部分。

我们接下来将会分离这些关注点,并单独分析该如何处理。尽管我们仍可以选择将这些关注点耦合起来,但这应该是一种有意识的决定。

一个重要的发现是:所有基于领导者的共识算法在选举新领导者时都会执行以下操作:

  1. 撤销已有的领导权。
  2. 建立新的领导者。

另一个约束条件是:撤销操作必须发生在建立之前,否则将导致多个领导者并存的问题。

对于基于多数派的共识算法,这个约束条件是原子性的:当一个领导者成功招募到所有必要的跟随者时,它就自动撤销了先前的领导权。

由于撤销操作是隐含完成的,它未被单独明确提出。更重要的是,它未被提出为一种可以分离的关注点。

换句话说,没有必要将这两个操作合并为一个动作来执行。对于非多数派的共识系统而言,这种分离尤为重要。

为了降低复杂性,本节将从领导权的建立与撤销入手。待分析完这两项操作后,我们会层层深入,加入其他关注点,例如:持续进展竞争条件处理以及请求传播

虽可分离但仍紧密相关

尽管建立与撤销操作可以分开执行,它们之间仍有强关系:

  • 领导权得以建立,是因为所有条件都满足,领导者可以成功完成请求。
  • 任一条件发生变化导致领导者无法完成请求时,撤销便发生。

提案编号(Proposal Numbers)

在传统共识算法中,领导权通过请求跟随者接受特定的提案编号得以建立。如果候选人设法让多数节点接受该编号,则认为领导权已成功建立。

撤销这种领导权则通过新候选人向这些跟随者发送不同的提案编号来完成,从而隐含地撤销了原领导者对这些节点的请求传播能力。当多数派跟随者达成一致,原领导者的撤销与新领导者的建立便同时完成。

无需提案编号(Without Proposal Numbers)

使用提案编号仅是实现建立与撤销领导权的众多方法之一。例如,在MySQL中,复制机制(replication mechanism)也可达到相同目标:

  • 为一个半同步副本指定主要节点,即是领导权的建立过程。
  • 请求该副本停止复制或从其他源复制,即达成撤销目标的方式。

知晓当前领导者

根据竞争条件处理方式,当前领导者可能未知。如果领导者未知,则撤销过程需针对所有可能的领导者。这意味着选举过程必须覆盖足够多的节点以确保没有现有领导者能够完成其请求。在下一篇文章中,我们会更详细讨论竞争条件问题。

直接领导者降级(Direct Leader Demotion)

现在我们已明确撤销是一个可以分开的操作,可以有不止一种方法对现领导者进行撤销:

  1. 如果当前领导者已知,请求其主动退出即可完成撤销。这通常更为优雅,因为领导者可以完成正在进行的请求,并通知客户端即将发生的领导权更动。
  2. 现领导者降级的方式只适用于计划内更动,例如软件更新。如果领导者因崩溃或网络分区而变得不可接触,则只能要求跟随者停止接受当前领导者的请求以实现撤销。

在Vitess中,我们通过两种操作实现领导权更动:

  • 计划内分片重选(PlannedReparentShard, PRS)
  • 紧急分片重选(EmergencyReparentShard, ERS)

对于软件更新,我们使用PRS将当前主要节点降级为副本,然后再进行更新。而若检测到主要数据库已宕机或不可接触,则使用ERS。

当执行PRS操作时,Vitess的低级组件vttablet进入过渡模式,只允许现有事务完成,而拒绝新的事务。同时,前端代理(vtgate)队列这些新事务。PRS完成后,所有队列事务会转发到新主要节点,系统恢复正常,且不会给应用程序造成错误。

为什么使用两种方式?

一个典型集群可能每秒完成数千个请求,而软件更新可能仅是每日的操作;节点故障则可能是每月甚至更低频率的事情。

优化常见场景尤为重要。这意味着在软件更新期间,我们希望领导权更替过程能够尽可能优雅。例如,应用程序在此期间应避免出现错误。主动降级当前领导者的方法为我们提供了这个机会。

算法的互换性

我们是否能够假定两种不同算法具有互换性?答案是:可以。

假设领导权是通过满足条件A和B建立的。一种算法通过令条件A失效实现撤销,而另一种通过令条件B失效实现撤销。在这两种情况下,撤销操作均为成功。

一旦撤销完成,两种算法都必须令新领导者满足条件A和B,从而为后续轮次采用任意撤销方法提供支持。

其他方法

我们可以构思无数其他方法来建立和撤销领导权,只要撤销与建立条件得以准确满足,这些方法均是有效的。一个极端例子是:切断连接领导者与跟随者的网络电缆也可以作为撤销领导权的方法。

我曾听说过一个Google事件,为了停止一个失控的领导者,他们派遣了一名工作人员去物理关闭该机器的电源。

在下一篇文章中,我们将讨论处理竞争条件和确保持续进展的可能选项。届时,我们会重新评估这些方法。



扩展型共识算法:第四部分 – 领导建立与撤销插图

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

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

本文链接:https://www.choupangxia.com/2025/05/23/consensus-algorithms-at-scale-part-4/