土法炼钢兴趣小组的算法知识备份

【FoundationDB 内核】Coordinator 与集群配置:Paxos 边界、招募与恢复入口

文章导航

分类入口
databasestorage
标签入口
#foundationdb#coordinator#cluster-controller#paxos#recovery#configuration

目录

客户端要连上 FoundationDB,手里通常只有一份 cluster file:里面是 Coordinators 的 IP:PORT 列表。集群重启、换机器、事务系统换代之后,业务进程仍靠这份列表找到「现在的配置权威」。若把 Coordinators 理解成「又一个 etcd」,会误判两件事:用户数据并不存在 Coordinators 上;每次 set 也不走一轮 Paxos。

本文是系列第 3 篇,钉三件事:Coordinators 持久化什么、Cluster Controller 如何成为招募入口、以及 Paxos 在 FDB 里的职责边界。完整恢复 epoch、旧 Log 封印与 RV 计算留给第 13 篇;Raft 选举教科书见 raft-explained,本文不重讲。

本文是「FoundationDB 内核」系列第 3 篇(共 18 篇)。→ 系列目录

篇目 核心内容
第 2 篇 · Client API 事务契约
第 3 篇 · Coordinator 配置、Paxos 边界、招募
第 4 篇 · Proxy Grv / Commit 与批处理

版本锚定:Zhou et al., SIGMOD 2021 §2.3.1 Control Plane、§2.3.4–2.3.5 Bootstrapping / Reconfiguration;FoundationDB 7.x Architecture(Coordinators、Cluster Controller、Master/Sequencer 招募);Active Disk Paxos 引用 Chockler & Malkhi 等工作(论文 Related Work / 控制面描述)。源码侧角色名在 fdbserver/ 中可见,本篇以论文与官方架构文档为准。


一、Cluster file:发现配置权威,不是发现数据副本

官方 Architecture:客户端与服务器都通过 cluster file 中的 Coordinators 地址接入;双方用 Coordinators 联系 Cluster Controller。服务器在尚无 Controller 时尝试竞选;客户端则通过 Controller 获取最新的 Grv Proxy / Commit Proxy 列表。

因此 cluster file 的语义是:

  1. 引导发现:谁是当前配置与成员信息的入口。
  2. 不是分片路由表:业务 key 落在哪台 Storage Server,由事务系统元数据与 Proxy 提供的映射决定(\xff 系统键空间,第 4、11 篇)。
  3. 可变更但仍须可达多数:Coordinators 集合变更是运维级操作;错误缩减多数会失去配置仲裁。
flowchart LR
  client["Client"]
  servers["fdbserver processes"]
  coord["Coordinators<br/>cluster file endpoints"]
  cc["Cluster Controller"]
  client -->|"cluster file"| coord
  servers -->|"cluster file"| coord
  coord -->|"elect / locate"| cc
  cc -->|"proxy list / roles"| client
  cc -->|"recruit roles"| servers

1.1 Coordinators 上有什么

论文 §2.3.1:控制面把事务系统配置等关键系统元数据持久化在 Coordinators 上;Coordinators 组成 disk Paxos 组,并选出单例 Cluster Controller。

Bootstrapping 链条(论文 §2.3.4)进一步说明分层存放:

信息 主要存放位置
用户数据与大部分系统元数据(0xFF 前缀等) Storage Servers
Storage Server 相关元数据 经由 Log / 恢复路径进入事务系统状态
Log System 配置(有哪些 Log Server) Coordinators(配置权威)

一句话:Coordinators 记住「这一代事务/日志系统长什么样」,而不是替 Storage 存业务 KV。


二、Cluster Controller:单例编排器

Cluster Controller 由 Coordinators 多数选举产生(官方 Architecture;论文称 disk Paxos 组选出 singleton)。它的职责包括:

论文 §2.3.1:Controller 招募三个单例——SequencerData DistributorRatekeeper;它们失败后会被重新招募。官方文档补充:自 6.2 起,Data Distributor 与 Ratekeeper 的生命周期不再与 Master/Sequencer 进程绑死,而是由 Cluster Controller 监控的独立单例。

flowchart TB
  coord["Coordinators<br/>Paxos group"]
  cc["Cluster Controller<br/>singleton"]
  seq["Sequencer / Master"]
  dd["Data Distributor"]
  rk["Ratekeeper"]
  coord -->|"elect"| cc
  cc -->|"recruit"| seq
  cc -->|"recruit"| dd
  cc -->|"recruit"| rk

2.1 谁招募 Proxy、Resolver、TLog

论文有一处「历史原因」表述:Sequencer 同时负责招募 Proxies、Resolvers 与 LogServers(§2.3.2)。官方 Architecture 则描述:Master 协调写子系统换代;写子系统包括 master、GRV proxies、commit proxies、resolvers、transaction logs;其中若干角色作为整体替换。

对本系列读者,记住操作语义即可:

  1. Cluster Controller 保证有一个活着的 Sequencer(Master)世代。
  2. 该世代的 Sequencer 拉起与自己绑定的 Proxy / Resolver / Log 集合。
  3. 任一生死监控范围内的角色失败,常触发整代事务系统恢复,而不是只热修单个进程(论文 §2.3.5「Make failure a common case」)。

细节状态机见第 13 篇;本篇只钉「配置权威 → Controller → Sequencer → 事务角色」这条招募链。


三、Paxos 边界:配置共识 ≠ mutation 共识

站内 raft-explained 讨论的是复制状态机安全;FDB 控制面用 Active Disk Paxos(论文引用)解决的是另一类问题:少数机器上的配置如何在故障下仍有唯一权威

层级 机制 复制的对象
Coordinators Disk Paxos / 多数 事务系统配置、锁世代等控制面状态
Log Servers 复制策略(论文:\(f+1\) 等部署选项) 已提交 mutation 的 WAL
Storage Servers 多副本 shard 版本化用户数据

用户 tr.set 的成功路径是:Resolver 通过 → Log durable → 向客户端确认,并不在 Coordinators 上为每个 mutation 跑 Paxos。Coordinators 在恢复时被 Sequencer 锁定并更新,防止双主世代(论文 §2.4.4)。

flowchart TB
  subgraph paxosBoundary ["Paxos boundary"]
    cfg["Cluster configuration<br/>and generation lock"]
  end
  subgraph commitPath ["Per-commit path"]
    occ["OCC on Resolvers"]
    log["Replicated Log Servers"]
  end
  subgraph readPath ["Read path"]
    ss["Sharded Storage Servers"]
  end
  cfg -.->|"recruits / epochs"| commitPath
  commitPath -.->|"async"| readPath

3.1 重配何时发生

论文 §2.3.5:当事务系统或日志系统出现故障,或数据库配置变更时,走 reconfiguration:Sequencer 监控 Proxies / Resolvers / LogServers,异常则自杀;Cluster Controller 发现后招募新 Sequencer,新 Sequencer 按 bootstrap 流程拉起新一代 TS/LS,并把新配置写入 Coordinators。

官方 Architecture 补充工程细节:恢复会 快进时间约 90 秒,使进行中的客户端事务因 transaction_too_old 失败并在重试时挂到新世代——这把「旧 Proxy 是否还在发版本」类问题收束到统一客户端重试路径。

常见误解

  1. 「Coordinators 像 ZooKeeper,所有元数据都在上面」。大部分系统元数据在 Storage 的 \xff 空间;Coordinators 关键是事务/日志系统配置与控制面仲裁。
  2. 「FDB 不用共识」。控制面用 Paxos;数据面提交用日志复制 + OCC。去掉的是「每个写都在 \(2f+1\) 上投票掩盖故障」的默认策略(论文 Abstract)。
  3. 「改 cluster file 里的地址等于完成扩容」。进程角色由 Controller / Sequencer 招募与数据分布决定;只改文件而不完成协调员变更与进程加入流程,会导致发现失败或脑裂风险。

四、学术谱系与开放问题

谱系:磁盘 Paxos / Active Disk Paxos 把稳定存储上的共识从「内存进程 + 不稳定网络」变体中分出(Chockler & Malkhi 等;论文控制面引用)。FoundationDB 把它用在窄接口:只仲裁配置与世代,把高频事务路径留给无锁 OCC + 日志。

与 TiKV / PD 对照:TiKV 用 PD 存 Region 路由并用 etcd/Raft 管 PD;每次写仍进 Region Raft 组。FDB 用 Coordinators 管事务系统世代,写进 Log Server 集合。两者都有「元数据服务」,但 写路径是否每值走共识组 不同——第 5、18 篇继续对照。

开放问题:急切重配降低副本数需求,却把可用性与 MTTR 绑定(论文原则 Fail fast)。在广域、高抖动网络下,误检导致的频繁世代切换是否可接受,是部署拓扑选择问题,而非单纯调大超时能消掉。第 13、16 篇从恢复与运维再写。


五、bootstrap 故事:空集群如何长出一代事务系统

用论文 §2.3.4 的顺序把「第一次有事务系统」讲成可记忆的故事(生产升级/恢复是同一骨架的变体):

  1. 进程们拿着同一份 cluster file 找到 Coordinators;尚无 Cluster Controller 时,服务器竞选,Paxos 组选出 Controller。
  2. Controller 招募 Sequencer(以及 Data Distributor、Ratekeeper)。
  3. 新 Sequencer 读 Coordinators 里记录的 Log System 配置(若有),拉起新的 Proxy / Resolver / Log 集合,并从旧日志路径恢复系统元数据(含 Storage 信息)。
  4. 恢复完成后,Sequencer 把 LS 配置写回 Coordinators。
  5. 此后客户端经 Controller 拿到 Proxy 列表,才能稳定取版本与提交。
sequenceDiagram
  participant S as fdbserver
  participant Co as Coordinators
  participant CC as Cluster Controller
  participant Seq as Sequencer
  S->>Co: locate / elect CC
  Co-->>CC: elected
  CC->>Seq: recruit
  Seq->>Co: read prior LS config
  Seq->>Seq: spawn TS and LS
  Seq->>Co: write new LS config
  Note over Seq: Ready for client commits

没有外部依赖(ZooKeeper / etcd)是刻意选择:配置权威内建在 Coordinators,避免「元数据服务的元数据服务」递归。代价是协调员集合本身必须被正确运维——丢多数等于丢配置仲裁。

5.1 与 raft-explained 的接缝

raft-explained 证明的是:已提交日志在何种投票规则下不会被覆盖。FDB 控制面要的是:同一时刻至多一个世代持有配置锁。二者都是共识,但复制对象与频率差几个数量级。读本系列时,把「共识」一词默认加上宾语——共识的是配置,还是用户 mutation。

5.2 运维上容易踩的坑(机制向)

下列条目来自官方架构语义的推论,不是本站事故复盘:

  1. 协调员多数不可用:无法选举或锁定配置,事务系统无法安全换代。
  2. cluster file 与真实协调员集不一致:部分客户端连旧集、部分连新集,表现为间歇性无法发现 Proxy。
  3. 把 Coordinators 当监控中心疯狂轮询:控制面为低频元数据设计;发现路径应缓存 Controller / Proxy 列表并在错误时刷新。
  4. 假设「只重启一台 Storage」等于「只丢读容量」:若同机还共址了 Sequencer/Proxy,可能触发写子系统恢复——共址策略要把故障域考虑进去(第 16 篇)。
flowchart LR
  bad1["Stale cluster file"] --> sym1["Cannot find healthy proxies"]
  bad2["Lost coordinator quorum"] --> sym2["Cannot reconfigure safely"]
  bad3["Colocated sequencer death"] --> sym3["Write epoch recovery"]

5.3 配置变更与事务世代的关系

官方把数据库配置变更也列为触发 reconfiguration 的原因之一(与进程失败并列,论文 §2.3.5)。含义是:改复制因子、改日志相关配置等,往往不是「热更新局部参数」,而是换一代事务系统。运维窗口应按「可能写暂停数百毫秒到数秒」来预留,而不是按「改一下 conf 无感」来预留。具体操作步骤以 7.x Administration 文档为准;本系列只钉机制:配置写在 Coordinators,生效路径经过 Sequencer 换代。

把 Coordinators 想成「低频、高后果」组件:改错一次的爆炸半径是控制面,不是某一个 shard。备份 cluster file、变更时维护多数、变更后验证客户端都能发现新 Proxy 列表,是机制推论出的操作纪律。

与第 1 篇 Unbundled 全景对照:数据面可以水平加 Storage / Proxy,但控制面的正确性前提是 Coordinators 多数一直在。扩容叙事里先保证协调员与 Controller 健康,再谈加 Storage。第 13 篇会回到「换代时写暂停、读边界」的精确语义。

(本篇不展开 Active Disk Paxos 的消息图;需要协议细节时回到论文引用与 raft-explained 的安全不变量对照即可。)


六、小结

三句话小结

  1. Coordinators 经 cluster file 对外暴露,用磁盘 Paxos 持久化事务系统配置并选举 Cluster Controller;它们不是业务 KV 的存放地。
  2. Cluster Controller 招募 Sequencer / Data Distributor / Ratekeeper;Sequencer 再拉起与本世代绑定的 Proxy、Resolver、Log Server。
  3. Paxos 的边界停在配置与世代锁;用户提交走 OCC + Log 复制。完整恢复状态机见第 13 篇。

下一篇进入客户端每天实际打到的入口:Proxy:读版本与提交入口


参考资料

核心论文

  1. Zhou et al., SIGMOD 2021, §2.3.1–2.3.5、§2.4.4(控制面、bootstrap、reconfiguration、recovery lock)。

规范 / 文档

  1. FoundationDB Architecture — Coordinators、Cluster Controller、Master、Transaction System Recovery(7.x)。
  2. FoundationDB Administration 文档 — cluster file、coordinator 变更(7.x,运维步骤以官方为准)。

站内

  1. raft-explained(共识安全;本篇不重讲)。
  2. 第 1 篇 Unbundled 全景
  3. 本系列 index

上一篇Client API 与事务模型

下一篇Proxy:读版本与提交入口

返回 系列目录 · 数据库索引

同主题继续阅读

把当前热点继续串成多页阅读,而不是停在单篇消费。


By .