我们如何将节点集群重建速度提升 15 倍
作者:Alchemy Team

我们大部分可靠性方面的工作在设计上是不可见的。你发送一个 RPC 请求,几毫秒内得到响应,你从不会去想是哪台机器提供了这个响应。这正是它应有的样子。但在这一个请求的背后,是一支必须在多个地区、跨多条链、全天候保持健康的区块链节点机群。让这支机群在大规模下保持健康,归根结底是一个数据搬运的问题,而且是一个比大多数人想象中要大得多的问题。
这篇文章讲的是我们为解决这个问题所做的一项具体投入:我们自研的一套高带宽、并行化的数据传输系统,配合我们机器之间的一条专用私有网络。两者结合,让我们能够以过去一小部分的时间重建节点存储。这首先是一项可靠性投入,而可靠性正是在硬件出故障时保持延迟低且_稳定_的关键。它是客户依托我们的节点基础设施所获得的可用性保障中的一个环节,而不是我们保障延迟的全部故事。
先说清楚这个说法诚实的一面:在正常的一天里,这并不会让某一次 RPC 调用更快,因为它不在你的请求路径上。它真正做的,是在机器出故障、你的延迟最受威胁的那一刻,让恢复变得快速且可靠。所以从这个意义上说,它确实支持了低延迟——在真正要紧的边缘情况下。
我们究竟在恢复什么?
这个问题值得直接回答,因为"恢复"可能有好几种含义。这里说的是把节点状态(节点回答请求所需的磁盘上的区块链数据集)恢复到健康的硬件上。这不是在恢复某一个失败的请求、传输中的数据,也不是在恢复物理硬件本身。
我们在三种情况下会用到它:
- 节点故障或性能下降。 硬件或其磁盘出现问题,我们需要启用替换节点,并快速把完整的链状态加载上去。
- 我们扩充容量。 某条链的流量增长,我们需要更多健康的节点来承载它,每个节点在接入流量之前都需要完整的数据集。
- 我们上线新链或新地区。 新节点启动时是空的,需要加载数太字节的状态数据才能派上用场。
这三种情况下,瓶颈都是一样的:要把一个庞大且不断增长的数据集快速、可靠地搬到新硬件上。
为什么重建一个区块链节点是一个数据搬运问题?
一个区块链全节点或归档节点体量不小。根据链的不同,其磁盘状态从数百 GB 到数 TB 不等,而且每天都在增长。每当我们遇到上述任一情况,都必须把这些状态快速搬到新硬件上。
有两种慢方法可以做到这一点。一种是从网络同步,让节点从其对等节点重放历史,对于一条大链,这可能要花上好几天。另一种是从一个已有的健康节点复制状态。复制比从零同步快得多,因此这是我们优化的路径。
问题在于:如果一次只在一个节点上操作,走共享网络路径,用一个从未为此规模设计过的工具,复制数太字节的数据仍然很慢。
什么是 rsync,我们为什么超出了它的能力范围?
我们并不是一开始就着手构建新东西。多年来我们一直使用 rsync,这是在机器之间复制和同步文件的标准 Unix 工具。
它是什么。 rsync 把文件从一台机器复制到另一台机器,并且对重复运行很智能:它使用一种滚动校验和的增量算法,只传输文件中发生变化的部分,而不是重新复制全部内容。它经受过长期考验、应用广泛,其增量传输方式让增量复制的成本很低。在两台机器之间同步数据集这件事上,它很难被超越。
它在哪里跟不上我们的需求。 rsync 是为在两台主机之间同步文件而设计的,而不是为了在时间压力下把数太字节数据搬到新硬件上。在我们的规模下,它撞上了一个硬性限制:吞吐量。单个 rsync 数据流基本上是串行的,远远达不到饱和我们所运行的高速网络和存储硬件的程度,因此大量可用带宽处于闲置状态。在机群规模下,这种被浪费的容量累积起来,就是每个节点数小时的重建时间,以及实实在在的运维拖累。rsync 本身没有错。我们只是超出了它最初被设计要完成的任务范围。于是我们构建了一个从一开始就为一个目标而设计的传输工具:以硬件所能允许的最快速度,把庞大的数据集搬到新节点上。
我们是如何做到的:专用私有网络加并行传输工具
我们同时从两个方向攻克这个问题:路,和车。
路:一条专用私有网络
我们把批量节点数据传输迁移到了我们机器之间的一条专用私有网络上,与承载生产流量的路径分开。
一旦复制走这条私有网络,有两件事随之改变。第一,批量传输不再与生产请求流量争抢资源,因此一次大规模重建不会让面向客户的延迟承担风险。第二,它在节点之间提供高且可预测的带宽:这正是传输工具所设计用来利用的原始容量,最高可达每秒数十 Gb。
车:一个专为此设计的并行传输工具
我们的自研工具只做一件事:尽可能快地把一整套节点状态目录从健康的源机器推送到目标机器。其设计围绕着让一条单一串行复制原本会大部分闲置的高带宽链路达到饱和而展开。有三个思路在发挥作用:
- 大量并行连接。 传输不是走一条数据流,而是同时跨越许多并发的 TCP 连接运行,这样才能真正填满私有网络的带宽。
- 拆分超大文件。 单个数太字节的状态文件会成为一条连接的瓶颈,因此超过一个可配置大小阈值的文件会按字节偏移量被拆分成多个块,每个块通过自己的连接并行发送。目标端将每个块直接写入文件中对应的偏移位置。
- 批量处理小文件,并优先处理最大的文件。 许多小文件被打包在一起以摊薄每次传输的开销,而最大的文件会最先开始传输,这样耗时最长的传输任务能立即启动。
编排:Ansible 与 AWX
一个快速的传输工具,只有在你能够可靠地驱动它跨多台机器运行、而无需人工手动输入命令时,才真正有用。我们用 Ansible 来编排重建任务,它可以在许多服务器上执行既定任务,并通过其任务与调度控制平面 AWX 进行管理。
带来的结果是,一次重建变成了一个可重复、可审计的任务:选定目标、启动工作流,然后让系统并行地通过私有网络搬运状态数据——每次都能得到一致的结果。
我们的方案比 rsync 快多少?
我们的工具快 10 到 15 倍。单线程的 rsync 以每秒 100-200 MB 的速度搬运节点状态。而我们的并行化传输能够维持每秒 2-3 GB。
这种速度的差异,在真正的重建中体现得尤为明显。在一次生产环境的运行中,我们重建了一个由 13 个节点组成的 Base Mainnet 机群(一个源节点,十二个目标节点),实际的数据传输在约 35 分钟内完成,包括私有网络的搭建与拆除在内的完整工作流则耗时约 1 小时 27 分钟,并且零故障、零不可达节点。而过去那种逐节点的做法,会把同样的重建拖成一场耗时数小时的苦战。
这对使用 Alchemy 的你意味着什么
这是一项基础层能力,因此它的好处会惠及运行在我们节点机群之上的任何产品。其机制始终相同(一次硬件故障在它可能集中放大负载、推高尾部延迟之前就先行愈合),但具体对你而言,按产品来说意味着以下这些:
- Node & RPC APIs(Alchemy 的 RPC API): 在一次节点故障期间,你的 p95/p99 响应时间保持稳定,因为一个性能下降的节点会在幸存节点被压垮之前就被替换。对你的用户而言,慢请求的高峰会更少。
- 数据与索引 APIs(Transfers、Balances、Token、Webhooks): 在后端节点重建时,你所消费的数据出现的空缺和滞后更少,因为恢复窗口是几分钟而不是几小时。数据更可信,而且更快可用。
- Rollups 与链服务: 你的专属或应用专用链能更快恢复容量,因此一次单点硬件故障不会演变成应用长时间处于性能下降状态的窗口。
这些是实实在在的_一致性_收益:我们通过让困难时刻变短、变少,来保持你的体验始终快速。
为什么这对那些从未看到它的人也很重要
这里说说它和你的应用之间的联系。当一个节点性能下降或发生故障时,它的流量必须转移到其余健康的节点上。如果重建替换节点的速度慢,这种压力就会在幸存节点上停留更长时间,而集中的负载正是推高_尾部延迟_的元凶:也就是那些作为你最慢请求呈现出来的 p95 和 p99 响应时间。(关于这种效应的经典论述,参见 Dean 和 Barroso 的 The Tail at Scale。)快速恢复缩短了这个窗口。机群会在这种性能下降被你感受为一次慢响应之前就完成自我修复。
这正是我们所说的"为故障做规划"的含义。我们不假设机器会一直正常运行。我们假设它们终将出故障,并为此投入资源,让故障影响保持很小、让恢复保持很快。这套传输系统以及它背后的私有网络,就是这类投入之一:这类基础设施的全部职责,就是确保我们数据中心里的一次硬件问题,永远不会变成你应用里的一次延迟问题。
你大概率永远不会注意到这一切。而这正是重点所在。
更大的图景:快,以及在压力下也快
在健康的一天里报出一个漂亮的延迟数字并不难。更难、在生产环境中真正要紧的说法是:在出问题的时候依然保持快速。低延迟不只是一种稳态下的属性,它更是系统在故障_期间_如何表现、以及恢复速度有多快的属性。这也是我们一开始就运行异构、冗余的节点基础设施的原因。
这正是我们保障延迟的方法之一:对恢复路径进行有意识的投入,让你所依赖的响应时间不仅在一切正常时保持稳健,在凌晨三点一台机器宕机、必须在任何人察觉之前完成重建时,同样保持稳健。
这是我们对自己的要求标准。这也是为什么 Alchemy 的性能工作会一路延伸到我们能以多快的速度在两台机器之间搬运一太字节数据这样的细节。
常见问题
这会让我的 RPC 请求变快吗?
在正常的一天里,不会。它不在你的请求路径上。但它会在最要紧的时刻——硬件出故障时——保护你的延迟。通过快速重建一个健康节点,它阻止了集中的负载推高你的 p95/p99,让你的最慢请求在压力下依然保持快速。
它究竟恢复了什么?
节点状态——即节点提供请求服务所需的磁盘上的区块链数据集。我们用它来替换故障节点、增加容量,或启用新节点或新地区。它不恢复单个请求,也不恢复物理硬件。
为什么不直接用 rsync?
rsync 非常适合在两台机器之间同步文件,我们也用了它很多年。但单个 rsync 数据流基本上是串行的,因此在机群规模下,它无法让我们的网络和存储硬件达到饱和,累积起来就是每个节点数小时的重建时间。我们的工具把传输分散到许多并行连接上,并把超大文件拆分到这些连接中,以充分利用一条专用私有网络的全部带宽。
更快的节点恢复如何改善延迟?
当一个节点出故障时,它的负载会转移到其余健康的节点上。重建耗时越长,这种集中的负载推高尾部延迟的时间就越长——也就是用户感受为最慢请求的 p95 和 p99 响应时间。更快的恢复缩短了这个窗口,使故障不会表现为慢响应。
它比 rsync 快多少?
在原始传输吞吐量上大约快 10 到 15 倍:单线程 rsync 数据流大约为每秒 100-200 MB,而我们通过私有网络进行的并行化传输可达每秒 2-3 GB。在实践中,这把一次耗时数小时的机群重建,变成了数据传输本身约 35 分钟即可完成的过程——在一个 13 节点的 Base Mainnet 机群中实现了零故障。
想在以这种方式打造的基础设施之上构建吗?前往 alchemy.com/docs 查看文档。
Alchemy 新闻通讯
第一时间获取发布信息
订阅我们的新闻通讯
获取 Alchemy 的最新产品更新和资源
填写您的电子邮箱地址即表示您同意接收我们的营销通讯和产品更新。您确认 Alchemy 按照我们的隐私声明处理我们收到的信息。您可以随时取消订阅。


