---
title: "我們如何將節點叢集重建速度提升 15 倍"
description: "大多數可靠性方面的工作都是隱形的。以下說明 Alchemy 如何透過平行傳輸與私有網路重建節點狀態復原機制，在硬體故障時維持延遲的一致性。"
---

# 我們如何將節點叢集重建速度提升 15 倍

<ImageBlock
  src="https://media.alchemy.com/blog/how-we-rebuild-node-fleets-15x-faster-hero.png"
  alt="節點復原速度快 15 倍"
  width={1024}
  height={480}
  priority
/>

我們大部分的可靠性工作，依照設計是看不見的。你發出一個 RPC 請求，幾毫秒內得到回應，完全不會去想是哪台機器處理的。這本來就該是這種感覺。但在這一個請求背後，是一整支必須全天候維持健康的區塊鏈節點艦隊，橫跨多條鏈、多個地區，不能中斷。要在這種規模下維持節點艦隊的健康，本質上是個資料搬移問題，而且比大多數人想像的要大得多。

這篇文章要談的是我們為解決這個問題所做的一項具體投資：一套我們自行打造的高頻寬、平行化資料傳輸系統，搭配機器之間專用的私有網路。兩者合在一起，讓我們能以過去一小部分的時間重建節點儲存。這首先是一項可靠性投資，而可靠性正是硬體故障時能維持延遲低且*穩定*的關鍵。它是客戶在我們的節點基礎設施上所依賴的可用性保證中，一個經過深思設計的環節，而不是我們捍衛延遲的全部手段。

先把話說清楚：這套系統在平常日子不會讓單一 RPC 呼叫變快，因為它根本不在你的請求路徑上。它做的是在機器故障的當下，讓恢復變得快速可靠——而那正是你的延遲最有風險的時刻。所以，沒錯，它確實支撐了低延遲，只是發生在真正重要的邊界情況裡。

## 我們實際在恢復什麼？

這個問題值得直接回答，因為「恢復」可能有好幾種意思。我們談的是把**節點狀態**（節點要回答請求所需的磁碟上區塊鏈資料集）復原到健康的硬體上。這不是恢復單一失敗的請求、傳輸中的資料，也不是恢復實體硬體本身。

我們會在三種情況下用到它：

- **節點故障或效能劣化。** 硬體或其磁碟不健康，我們得啟用替代機器，並快速把完整的鏈上狀態載入。
- **我們要增加容量。** 某條鏈的流量成長，我們需要更多健康的節點來服務，而每個節點在承接流量前都需要完整的資料集。
- **我們要啟用新鏈或新地區。** 新節點一開始是空的，需要數 TB 的狀態資料才能派上用場。

三種情況下，瓶頸都一樣：要把一份龐大且不斷成長的資料集，快速可靠地搬到新硬體上。

## 為什麼重建區塊鏈節點是個資料搬移問題？

一個區塊鏈全節點（full node）或存檔節點（archive node）不是小東西。依鏈而異，其磁碟上狀態從數百 GB 到數 TB 不等，而且每天都在成長。每次我們遇到上述任一種情況，都得把那份狀態快速搬到新硬體上。

有兩種慢方法可以做到這件事。你可以從網路同步，讓節點向其對等節點重放歷史，但對大型鏈來說可能要花好幾天。或者，你可以從你已經在跑的健康節點複製狀態。複製比從頭同步快得多，所以這是我們優化的路徑。

問題在於：如果你一次只搬一個節點、走共用網路路徑、又用一個從來不是為這種規模設計的工具，複製幾 TB 的資料仍然很慢。

## 什麼是 rsync？我們為什麼超出它的能力範圍了？

我們一開始並不是打造新東西。多年來我們用的是 `rsync`，這是 Unix 標準的機器間檔案複製與同步工具。

**它是什麼。** `rsync` 會把檔案從一台機器複製到另一台，並且對重複執行很聰明：它用滾動校驗和（rolling-checksum）差異演算法，只傳送檔案中變動的部分，而不是整份重新複製。它經過長年實戰考驗、無所不在，其差異傳輸方式讓增量複製變得便宜。就兩台機器之間同步資料集而言，很難找到比它更好的。

**它在我們這裡失效的地方。** `rsync` 的設計目的是在兩台主機之間同步檔案，而不是在時間壓力下把數 TB 資料搬到新硬體上。在我們的規模下，它撞上了一個硬上限：吞吐量。單一 `rsync` 串流基本上是序列化的，遠遠無法把我們所用的高速網路與儲存硬體跑滿，導致大量可用頻寬閒置。在艦隊規模下，這種浪費的容量累積成每台節點數小時的重建時間，以及實質的維運拖累。`rsync` 並沒有錯，只是我們的需求已經超出它原本設計的範圍。於是我們打造了一個從一開始就為單一任務設計的傳輸工具：以硬體所能允許的最快速度，把龐大的資料集搬到新節點上。

## 我們怎麼做：專用私有網路加上平行傳輸工具

我們同時從兩個方向下手：路和車。

### 路：專用私有網路

我們把大量節點資料傳輸移到機器之間的專用私有網路上，與服務正式流量的路徑分開。

一旦複製走這條私有網路，有兩件事會立刻改變。第一，大量傳輸不再與正式請求流量競爭，所以大規模重建絕不會讓面向客戶的延遲陷入風險。第二，它在節點之間提供高且可預測的頻寬：這正是傳輸工具設計來運用的原始容量，最高可達每秒數十 Gb。

### 車：專為目的打造的平行傳輸工具

我們自製的工具只做一件事：盡可能快速地把一整個目錄的節點狀態，從健康的來源機器推送到目的機器。這套設計的核心，就是把一條高頻寬連線跑滿——單一序列複製會讓這條連線大部分時間閒置。有三個構想在發揮作用：

- **大量平行連線。** 傳輸不是走單一串流，而是同時橫跨許多並行的 TCP 連線，這樣才能真正填滿私有網路的頻寬。
- **拆分超大檔案。** 單一數 TB 的狀態檔案會讓單一連線成為瓶頸，所以超過可設定大小門檻的檔案會依位元組偏移量切成多個區塊，每個區塊各自透過獨立連線平行傳送。目的端會把每個區塊直接寫入檔案中正確的偏移位置。
- **批次處理小檔案，並優先傳最大的檔案。** 大量小檔案會被分組打包，以分攤每次傳輸的開銷；而最大的檔案會最先開始傳送，讓耗時最長的傳輸盡早進行。

### 協調調度：Ansible 與 AWX

一個快速的傳輸工具，只有在能可靠地跨多台機器驅動、而不需要有人手動打指令時，才真正有用。我們用 Ansible 來協調重建工作，它會在多台伺服器上執行定義好的任務，並透過其工作與排程控制平面 AWX 來管理。

結果是，重建變成一項可重複、可稽核的作業：選定目標、啟動工作流程，讓系統把狀態平行地搬過私有網路——每次結果都一致。

## 我們的解決方案比 rsync 快多少？

我們的工具快 10-15 倍。單執行緒的 `rsync` 搬運節點狀態的速度是每秒 100-200 MB。我們的平行化傳輸則能維持每秒 2-3 GB。

這種速度差異在真實重建中才顯出意義。在一次正式運行中，我們重建了一支 Base Mainnet 艦隊，共 13 個節點（一個來源、十二個目的地），實際資料傳輸在約 **35 分鐘**內完成，而包含私有網路建立與拆除在內的完整工作流程，則在約 **1 小時 27 分鐘**內完成，**零故障、零無法連線的節點**。過去那種逐節點的做法，同類重建往往要拖上好幾個小時。

## 這對你在 Alchemy 上意味著什麼

這是基礎層級的能力，所以它的效益會擴及到我們節點艦隊上運行的任何產品。運作機制始終一樣（硬體故障在還沒來得及集中負載、推高尾端延遲之前就先被修復），但以下是這對每項產品分別代表的意義。

- **Node & RPC APIs（Alchemy 的 RPC API）：** 即使發生節點故障，你的 p95/p99 回應時間仍能保持穩定，因為效能劣化的節點會在存活節點被過載之前就被替換掉。你的使用者遇到的慢請求尖峰會更少。
- **Data & indexing APIs（Transfers、Balances、Token、Webhooks）：** 當背後的節點被重建時，你所使用的資料中斷與延遲情況會更少，因為恢復只是一小段時間窗口，而不是數小時。資料更值得信賴，而且更快。
- **Rollups 與鏈服務：** 你專屬或應用專用鏈的容量恢復更快，因此單一硬體故障不會演變成你應用程式長時間的效能劣化窗口。

這些都是實質的*一致性*收益：我們透過縮短且減少艱難時刻，讓你的體驗維持快速。

## 為什麼這對從未看見它的人也很重要

這裡是與你的應用程式的連結所在。當一個節點劣化或故障時，它的流量必須轉移到其餘健康的節點上。如果重建替代節點很慢，這股壓力就會在存活節點身上停留更久，而集中的負載正是把*尾端延遲*（tail latency）推高的原因：也就是使用者感受到的最慢請求——p95 和 p99 回應時間。（這種效應的經典論述可參見 Dean 和 Barroso 的 [The Tail at Scale](https://research.google/pubs/the-tail-at-scale/)。）快速恢復能縮小這個窗口。艦隊在效能劣化還沒被你這端感受為慢回應之前，就已經自我修復了。

這就是我們說「為故障做準備」的意思。我們不假設機器會一直正常運作，我們假設它們會故障，並且投資讓故障維持在小範圍、讓恢復維持快速。這套傳輸系統與其背後的私有網路，正是這類投資之一：其全部工作，就是確保我們資料中心裡的硬體問題，永遠不會變成你應用程式裡的延遲問題。

你大概永遠都不會注意到這些。而這正是重點所在。

## 更大的全貌：快，而且在承壓下依然快

在一切正常的日子裡，貼出漂亮的延遲數字並不難。真正困難、也真正在正式環境中重要的說法，是在系統出問題時依然保持快速。低延遲不只是穩態下的特性，它也是系統在故障*期間*行為表現，以及恢復速度快慢的特性。這也是我們一開始就選擇運行異質、冗餘節點基礎設施的原因。

這是我們捍衛延遲的其中一環：對恢復路徑的刻意投資，讓你所依賴的回應時間，不只在一切正常運作時能維持，在凌晨三點某台機器故障、必須在被任何人察覺前完成重建時，也一樣能維持。

這是我們對自己的要求標準。這也是為什麼 Alchemy 的效能工作，會一路深入到我們能多快在兩台機器之間搬運一 TB 資料這種細節。

## 常見問題

**這會讓我的 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](https://www.alchemy.com/docs) _查看文件。_
