零停機、零缺口:我們如何打造具容錯能力的 Solana gRPC 串流
作者:Alchemy

對於建構交易基礎設施、MEV 搜尋機器人(searcher)、清算機器人(liquidation bot)與即時索引器(indexer)的團隊來說,產品的速度取決於供給它的資料。串流一旦出現峰值或斷點,就代表錯失一筆交易,或索引不完整。
這就是為什麼我們在多節點冗餘層之上打造了Solana gRPC streaming product,讓峰值與斷線在觸及你的 pipeline 之前就被吸收,你不需要在一個原本該是託管服務之上,自己建置容錯邏輯(failover logic)。以下是我們的架構設計方式。
為什麼 gRPC 在 Solana 上很重要
Solana 的資料輸出量非常龐大:尖峰時每年超過 4 PB。透過 JSON-RPC 進行傳統輪詢(polling)會帶來不必要的開銷:重複的請求、浪費的頻寬,以及請求-回應循環固有的延遲。對於需要在每筆帳戶更新或交易一經確認就立即取得的工作負載來說,輪詢無法勝任。
透過 Protobuf/HTTP2 進行 gRPC streaming 則翻轉了這個模型。伺服器在資料產生的當下就主動推送給客戶端。開發者只訂閱他們需要的資料——特定帳戶、程式(program)、交易模式——並取得一個持續、經過篩選的串流,零輪詢延遲。對於區塊時間低於一秒、資料量龐大的 Solana 而言,這是優先將最新資料傳遞給使用者的應用程式的理想解決方案。
Yellowstone gRPC 介面已成為 Solana streaming 事實上的標準。開發者已有現成的客戶端函式庫,涵蓋 Rust、TypeScript、Go,以及任何能編譯 .proto 檔案的語言。我們採用了這個標準,因此從任何相容於 Yellowstone 的供應商遷移,只是換個 URL,而不需要重寫程式碼。
架構:從 shred 到串流
我們的 streaming pipeline 有四層,每一層都內建冗餘設計,以確保大規模下的穩定效能。
Shred ingestion
Shred 是 Solana 上資料傳播的基本單位——大小符合 MTU 的訊框(約 1,280 bytes),內含區塊條目(block entry)的片段。網路透過 Turbine 廣播 shred,這是一種多跳(multi-hop)協定,驗證者(validator)透過分層的鄰近群組中繼資料。Turbine 速度很快,但本質上是機率性的。封包遺失會在各跳之間累積,位於樹狀結構深處的節點在組裝出完整區塊之前,可能需要等待數百毫秒進行缺口修復(gap repair)。
我們同時從多個獨立來源擷取 shred——包括直接從高權益(high-stake)驗證者收集 shred 的服務,繞過 Turbine 的多跳延遲。每個來源涵蓋不同的地理路徑與驗證者鄰近群組。一個串流中的缺口會由另一個來源補齊,這代表更快的區塊組裝,以及更少的修復週期。
這點很重要,因為節點需要達到最低數量的 shred 才能組裝出每個 slot。如果它在約 250 毫秒內收不到足夠的數量,就會退回修復協定——向其他節點請求缺少的 shred,這會增加顯著的延遲。在修復機制啟動之前取得足夠的 shred 是關鍵。這就是為什麼我們從多個獨立來源擷取資料:更多的涵蓋範圍代表節點能更快達到門檻,更早完成條目組裝,也更早觸發 Geyser 通知。這裡節省下來的每一毫秒,都會層層影響到下游。
Richat 引擎
我們 streaming 服務的核心是 Richat,一個開源引擎,以 Geyser 外掛(plugin)的形式在 Solana 節點上運行。它擷取帳戶更新、交易通知、slot 狀態、區塊中繼資料(metadata)與條目更新,這些資料由 Agave 客戶端產生的當下就被捕捉,接著串流傳送到 Richat server,作為彙整與分發層。
關鍵的設計決策在於:每個 Richat server 會同時連接多個上游 Solana 節點。它會跨來源去除重複的更新,並將最快的健康結果傳送到下游。當某個上游節點在某個 slot 上落後時,彙整層會改由下一個最快的節點提供資料。
這正是我們能夠削弱延遲峰值(latency spike attenuation)的原因。單節點部署在 p99 與 p999 延遲上會有長尾現象,因為上游節點的每一次異常都會直接傳遞給所有消費者。多節點彙整則能拉平這個長尾——開發者取得的串流,反映的是當下表現最好的節點,而不是唯一的那個節點。
開發者取得的串流
開發者可透過標準的 Yellowstone 客戶端函式庫連線。連線後,他們可以訂閱帳戶更新(附帶 program、owner 與 data-slice 篩選條件)、交易更新(附帶 account-include/exclude 與簽章篩選條件),以及 slot、block、block-meta 與條目更新。原生支援 commitment 等級(processed、confirmed、finalized)、Zstd 壓縮,以及伺服器端的 keepalive。
多個並行訂閱可以在單一連線上以 AND/OR 語意組合。雙向串流讓開發者能夠訂閱、修改與取消訂閱,而不需要重新連線。
重新連線時的回放(Replay)
短暫的斷線與客戶端重啟是無可避免的。問題在於,這是否會讓開發者遺失資料。
我們在 Richat 的環形緩衝區(ring buffer)中儲存了最近更新的滾動視窗(rolling window)。當客戶端重新連線時,可以附帶 from_slot 參數進行訂閱,補齊斷線期間錯過的所有資料,再接續即時串流。不需要另外的回填(backfill)pipeline,不需要維護缺口偵測邏輯,也不需要在消費端旁邊另外運行一個調節服務(reconciliation service)。
對於需要在長時間跨度上維持無缺口串流的開發者——例如索引器、分析平台,以及任何運行無法承受漏失更新的有狀態消費端(stateful consumer)——這是一個更簡單的維運模式。
接下來
目前的架構是基礎,而不是終點。我們正持續進行以下工作:
延長回放視窗。 大幅擴大重新連線的回填視窗,讓需要更長恢復涵蓋範圍的開發者受益。
硬體與網路最佳化。 持續進行基礎設施改善,以降低關鍵路徑上的延遲。
新增地區。 擴大涵蓋範圍,讓串流更靠近更多開發者與更多驗證者。
專屬部署。 針對少數將共置(co-location)與隔離視為必要條件而非偏好的團隊。
開始使用
Alchemy Solana gRPC 目前已在所有付費方案中提供,每 TB 起價 $75,沒有方案門檻,也沒有每月最低消費。如果你已經在使用 Yellowstone 客戶端,遷移只需要換個 URL。
- 閱讀文件
- 聯絡我們的團隊
- 申請 2,000 萬美元 Solana Fund,最高可獲得 25,000 美元的額度,加速你在 Solana 上的應用開發。
Alchemy 電子報
搶先掌握最新發布消息
訂閱我們的電子報
取得 Alchemy 最新產品更新與資源
輸入您的電子郵件地址,即表示您同意接收我們的行銷通訊與產品更新。您了解 Alchemy 會依照我們的隱私權聲明處理所收到的資訊。您可以隨時取消訂閱。


