跳转到内容

Aeron® 集群部署:如何选择可用区拓扑

Raft 集群的节点放在哪里,是一个同时决定热路径延迟和最坏情况爆炸半径的决策——而这两者恰好朝相反方向拉扯。本页梳理撮合引擎(ME)集群的几种基础拓扑——三种对称的赌注,外加介于其间的两种混合方案——逐一打分,并点出大多数交易所真正会上线的那个折中方案。

共识的字节级机制——任期、日志复制、提交——请看 The Aeron Files。本页只谈部署决策:选哪种拓扑、为什么,以及每一种在 p50/p99、可用性和运维开销上分别要你付出什么。

每个选择背后那个绕不开的取舍

Section titled “每个选择背后那个绕不开的取舍”

热路径是 OMS → Raft 主节点(订单写入路径)。只有主节点接受写入,所以交易所真正感受到的,就是从下单点到主节点所在位置的那段延迟。每个部署决策,其实都在回答同一个问题:

为了缩小故障的爆炸半径,你愿意在热路径延迟上让出多少?

把主节点放得近,p50/p99 就压得紧;为了韧性把集群铺开,就会把这段热路径——或者提交所需的多数派——拽过一道可用区边界。没有哪种部署能两头通吃。本页余下的部分,就是帮你有意识地在这条曲线上选定自己的位置。

七个维度,分越高越好

  1. 容错能力——你能扛住的最大故障域:节点 → 机架 → 数据中心 → 可用区 → 区域。
  2. 热路径延迟——OMS↔主节点的延迟。机架内 µs 级,还是跨区 ms 级?分越高代表延迟越低。
  3. 可用性——故障发生时,集群能不能自动撑住、继续对外服务?
  4. 恢复自动化——是自动重新选举,还是手动灾备切换,还是冷启动重建。
  5. 数据安全(RPO)——切换时丢失已提交 / 在途消息的风险。
  6. 成本效率——跨区流量、节点数量、带宽。分越高代表越省钱。
  7. 运维简单度——日常负担:主节点固定、复制监控、灾备手册。

3 个(或 5 个)Raft 节点,每个可用区放一个。教科书式的高可用布局:一套横跨整个区域的共识组。

代价在于:每次选举后,主节点都可能漂到 AZ-2 或 AZ-3。一旦漂走,OMS 每笔订单都要在 OMS→主节点这一跳吃跨区往返,直到你把它挪回来。而且即便把主节点钉在本地,提交仍然需要一次跨区的多数派 ack——投票成员分散在各可用区,所以无论主节点在哪,提交路径上至少压着一次跨区 ack。固定主节点只能把跨区延迟从面向客户端的路径上拿掉,却拿不掉提交路径上的。

主节点漂移这个问题并不致命——它恰恰是 preferred-leader 模式要解决的。把选举偏向选定的可用区、并在故障切换后把主节点收回来,见 主节点放置与优先主节点控制;这个收回过程有多快,见 调优优雅让位时间(实测:调优后 ~57 ms,默认 ~266 ms)。

维度分数
容错能力5 —— 扛得住整个可用区故障
热路径延迟2 —— 主节点漂移 + 提交始终跨区
可用性5 —— 自动重新选举,无需人工介入
恢复自动化5
数据安全(RPO)5 —— 零丢失,同步多数派
成本效率3 —— 节点数和 T3 一样,但要持续付跨区流量费
运维简单度2 —— 主节点固定 + 让位是运维最重的一项
总分27 / 35

在这些情况下选 T1:监管对可用性有硬性要求,可用区挂了必须零 RPO 自动顶上,且热路径上的跨区延迟可以接受。

T1.5 —— 拉伸式 2+1(本地多数派)

Section titled “T1.5 —— 拉伸式 2+1(本地多数派)”

一套 3 节点 Raft 集群,按 2+1 拆分:两个投票节点放在同一个可用区,第三个放在另一个可用区。诀窍在于多数派算术——3 个节点的多数派是 2,所以主节点和它同区的那个伙伴单靠自己就凑成了多数派。提交在区内确认,µs 级;只要两个热区投票节点都在、且主节点被钉在本地,那个 AZ-2 投票节点虽是正式成员,却从不落在提交路径上。

这买来的是从一套单一拉伸投票集群里拿到 T3 级别的提交延迟——这一点 T1(提交 ack 始终跨区)和 T2.5(跨区节点不投票)都给不了。代价是非对称的容错能力,而这正是这里的关键所在:

  • 丢掉少数派可用区(那个孤零零的 AZ-2 投票节点)或任何单个节点 → 集群自动扛过去。 剩下两个投票节点仍是多数派,提交继续走区内,RPO 为零——那个节点本来就不在提交路径上。
  • 丢掉多数派可用区(两个热区投票节点一起没)→ 集群停摆。 孤零零的幸存者凑不齐多数派(1 < 2),所以恢复是一次手动的单节点重配置,且 RPO > 0——因为提交从不等它,那个 AZ-2 投票节点可能滞后。这里的「多可用区」并不意味着像 T1 那样「自动扛住一个可用区故障」。
  • 主节点固定是硬性要求。 万一选举把主节点选到了 AZ-2 那个节点上,提交就得等一次热区 ack → 变成跨区提交,延迟优势随即蒸发。把优先主节点钉在多数派可用区——和 T1 修主节点漂移是同一套工具,见 主节点放置与优先主节点控制
  • 热区只有两个投票节点。 挂掉一个,提交多数派立刻就得靠那张跨区选票,于是在你修复之前 p99 会劣化。这恰恰是 T2.5 多出来的那个节点买回来的东西——T2.5 在热区保留三个投票节点,能不付跨区代价地扛过一次热区节点故障。
  • 放置组的选择,决定这两个热区投票节点是被绑在一起还是彼此隔离。 cluster 放置组把它们挤在一起换取最紧的区内 ack,但代价是共享底层设施——一次机架 / CPG 故障会把两个一起端掉,集群随之停摆。区内的 spread 放置组则让两个投票节点落在互相独立的故障域里,每次 ack 多花几个 µs。撮合引擎上,通常选 spread。
维度分数
容错能力3 —— 自动扛住一个节点或少数派可用区;多数派可用区停摆(手动)
热路径延迟4 —— 钉主时提交走区内,但热区只有两个投票节点;挂一个就退化为跨区
可用性4 —— 扛得住节点故障和少数派可用区故障;多数派可用区故障会让集群停摆
恢复自动化3 —— 节点级自动选举;多数派可用区故障要手动单节点重配置
数据安全(RPO)3 —— 常见的少数派可用区故障下为零,多数派可用区挂掉则 > 0
成本效率4 —— 一套集群、三个节点;一条跨区日志流,而非每次提交都跨区 ack
运维简单度3 —— 主节点固定是硬性要求,外加一份非对称故障手册,但毕竟只是一套 3 节点集群
总分24 / 35

在这些情况下选 T1.5:你只有两个可用区(做不了对称的 1-1-1 分布),想用最省钱的单一拉伸集群拿到区内提交延迟,并且能接受只有少数派可用区故障才自动恢复——多数派可用区死掉是一次手动、RPO > 0 的事件。若有三个可用区,通常 T1 或 T2.5 会更划算。

两套独立的 Aeron® 集群。主集群在一个可用区对外服务,它的归档日志异步复制到另一个可用区的备集群。真出了灾难,再由运维手动切换。

因为复制是异步的、不在热路径上,主集群就能跑出单可用区的速度——p50/p99 和 T3 一样。代价在备集群这边:它会滞后,所以硬切换时那些还没复制过去的消息就会丢(RPO > 0)。

跨区分发日志有两种方式,都是异步:

  • 接力 / 菊花链(1 条跨区流)。 主节点只发给一个备节点,再由它在区内转给其余两个。跨区带宽最省;多一跳区内转发,所以备集群尾延迟略高。
  • 广播(3 条跨区流)。 主节点同时发给每个备节点。备集群滞后最小、切换时 RPO 最低,代价是 3 倍跨区带宽。

接力 / 菊花链——一条跨区流,再在区内扇出:

广播——主节点直接发给每个备节点:

维度分数
容错能力4
热路径延迟5 —— 对外服务的集群在单可用区,跟 T3 一样
可用性4 —— 节点级故障的表现和 T3 完全一致(自动选举、零丢失)
恢复自动化4 —— 可用区级切换靠手动:发现、提升、改指向
数据安全(RPO)4 —— 只有硬切换时才 > 0
成本效率1 —— 6 个节点(3 个纯备用)+ 复制带宽;最烧钱
运维简单度2 —— 两套集群一起盯、复制延迟监控、灾备演练
总分24 / 35

在这些情况下选 T2:既要区内热路径的低延迟,要扛住整个可用区被端掉,并且能接受罕见硬切换时丢几条消息的 RPO 加上更长的手动 RTO。这是 CEX 最经典的平衡点。其中的机制——热备节点、原地身份切换、后台快照、菊花链——见 集群 Standby 与多可用区 HA 设计

所有 Raft 节点都在同一个可用区。延迟最低的布局,适合热路径不容妥协、而可用区级灾备另有方案的场景(通常是在上面再叠一层 T2)。

单可用区不等于单机架。把节点按 spread 放置组 / TAM 协调的布局分散到区内不同数据中心,既保住区内延迟,又能在节点之间拿到真正的故障隔离。

维度分数
容错能力2 —— 不具备可用区级容错;可用区一挂,集群跟着停
热路径延迟5 —— 区内 / 机架内 µs 级,没有主节点漂移,所有节点到 OMS 等距
可用性3
恢复自动化4
数据安全(RPO)3 —— 灾难场景最差:副本全在挂掉的那个可用区里
成本效率5 —— 一套集群,没有复制
运维简单度5 —— 没有主节点要固定,没有日志要复制
总分27 / 35

在这些情况下选 T3:撮合要榨干每一微秒,且可用区级灾备另行解决。

T2.5 —— 单可用区集群 + 一个跨可用区备份节点(性价比之选)

Section titled “T2.5 —— 单可用区集群 + 一个跨可用区备份节点(性价比之选)”

大多数对延迟敏感的交易所真正会上线的折中方案:热路径跑 T3,然后挂上一个跨可用区的 Cluster Standby 节点,让它持续把日志和快照拉到另一个可用区。

你保住了 T3 的 µs 级热路径和低成本(只多一个节点,不是三个),换来一张跨区安全网:灾难不再全丢,因为另一个可用区里有一份热的、已追平的日志副本。这个备份节点对主节点不施加任何反压——复制是异步的——所以主集群的 p50/p99/吞吐都不受影响。这是把 RPO 从”挂掉的可用区里还剩多少”这个境地里搬出来的最省钱办法。

相比 T2 的取舍:你只有一个备份节点,而不是完整的三节点备集群,所以可用区丢失后把它提升上线,比 T2 集群对集群的切换更靠手动、也更慢。如果罕见事件下几分钟、偏手动的 RTO 可以接受,T2.5 就能用 T2 一个零头的成本拿到它约 90% 的保护。

维度分数
容错能力3 —— 有一份热的跨区副本能幸存,但提升靠手动
热路径延迟5 —— 和 T3 一样;备份节点是异步的,不施加任何反压
可用性3 —— 节点故障自动选举(它就是一套在线的 T3 集群);可用区故障要手动提升
恢复自动化3 —— 区内自动;跨区提升是一个偏手动的节点,比 T2 的切换慢
数据安全(RPO)4 —— 区外有一份已追平的副本;只有硬性可用区故障时才 > 0
成本效率4 —— 一套集群 + 一个额外节点、一条日志流;远比 T2 那三个纯备用节点便宜
运维简单度4 —— 只运维一套集群,外加复制延迟监控和一份单节点提升手册
总分26 / 35
维度(分越高越好)T1 · 多可用区T1.5 · 2+1T2 · 主+备T2.5 · +备份节点T3 · 单可用区
容错能力53432
热路径延迟24555
可用性54433
恢复自动化53434
数据安全(RPO)53443
成本效率34145
运维简单度23245
总分 / 352724242627

两种混合方案,正好落在这张矩阵的对角线上。T1.5 是一套朝延迟倾斜的单一拉伸投票集群:它把多数派挤到同一区,换来区内提交(热路径延迟 4,对比 T1 的 2),代价是非对称的容错能力(3——只有少数派可用区故障才自动恢复)。T2.5 就是 T3(热路径数字相同),只是把容错 / RPO 往上抬了一点、再加一个节点——是有意朝 T3 那个角落靠拢、再加一道异步跨区兜底。两者都不在任何单一维度上拉满;它们的存在,就是为了避开那几个角落各自最糟的短板。

上面那个「数据安全(RPO)」的分数,其实把灾备方案里要分开看的两个数字压成了一个:RPO——一次故障最多丢多少已提交的数据;RTO——恢复对外服务前要停多久。两者都完全取决于挂掉的是哪个故障域,所以要按故障模式分开读,而不是当成一个笼统的数。表里的 RTO「自动」指 Raft 无需人工介入就重新选举(调优见 调优集群故障切换时间);「手动」指要走运维手册——提升 / 改指向——以分钟计。

拓扑单节点故障整个可用区故障
T1 · 多可用区RPO 0 · RTO 自动RPO 0 · RTO 自动——唯一能零数据丢失自动扛住可用区故障的拓扑
T1.5 · 2+1RPO 0 · RTO 自动少数派可用区: RPO 0 · RTO 自动。多数派可用区: RPO > 0(滞后的投票节点)· RTO 手动——单节点重配置
T2 · 主 + 备RPO 0 · RTO 自动(主集群内)RPO > 0(异步复制滞后)· RTO 手动——集群对集群切换
T2.5 · +备份节点RPO 0 · RTO 自动(主集群内)RPO > 0(异步复制滞后)· RTO 手动——单节点提升,比 T2 更靠手动、也更慢
T3 · 单可用区RPO 0 · RTO 自动RPO = 区内所有副本(这一层没有灾备)· RTO = 外部灾备 / 重建,除非上面叠了一层 T2

规律很清楚:只要故障后集群仍握有多数派,RTO 就是自动的;一旦恢复要跨过一道提交路径从未跨越的可用区边界,RTO 就变成手动。 RPO 在提交同步的地方恰好为零(T1 永远如此;T1.5/T2/T2.5/T3 的单节点故障也是),而在幸存副本靠异步喂数据(T1.5 的多数派可用区故障、T2/T2.5 的可用区切换)或根本不存在(T3 的可用区故障)的地方则为正。

自上而下走一遍这棵树——每个分叉都是关于你 SLA 的一个问题,走到的叶子就是该从哪种拓扑起步。下面的表格是同一个决策的查表版,把理由写得更细。

你的优先级拓扑
可用性 ≫ 延迟——受监管,可用区挂了必须零 RPO 自动顶上,跨区热路径延迟可以接受T1
只有两个可用区,又要单集群的区内延迟——从一套拉伸集群拿到 µs 级提交;接受只有少数派可用区故障才自动恢复T1.5(拉伸式 2+1)
延迟、可用性两头都要——区内热路径自动扛住整个可用区被端掉;CEX 最常见的平衡点T2
接近 T3 的性能 + 跨区兜底——榨延迟,但不想让一场灾难把数据全丢光T2.5(T3 + 一个跨可用区备份节点)
只要极致性能——每一微秒都重要,可用区级灾备另行解决T3

部署是一个决策,不是一次性锁死

Section titled “部署是一个决策,不是一次性锁死”

有两个后续问题,会把部署从一锤子买卖变成一件需要持续运维的事:

  • T1 的主节点漂移是可修的。 把选举偏向你选定的可用区,并在故障切换后收回主节点——见 主节点放置与优先主节点控制——再到 调优优雅让位时间 调优这个收回过程有多快。
  • 把一个在线集群在可用区或区域之间搬迁,是一份运维手册,不是一次重建。 当你把初始部署用到瓶颈——或者要迁到新区域时——你可以逐节点迁移(客户端透明、follower 免费),也可以整集群切换,而唯一有意义的停机就是那一次 leader 跨越,上面的优雅让位参数正好能把它压短。见 在线集群跨区域迁移

另见:集群 Standby 与多可用区 HA 设计Aeron® 集群与 Raft 共识调优集群故障切换时间非计划死亡的时间预算)。