Solana 上的 Streaming Blocks:数据量、延迟与不可避免的权衡

发布: (2026年2月10日 GMT+8 10:21)
11 分钟阅读
原文: Dev.to

Source: Dev.to

要将内容翻译成简体中文,请提供您希望翻译的完整文本(除代码块、URL 和技术术语外)。您可以直接粘贴文章的其余部分,我会在保持原始格式、Markdown 语法和技术术语不变的前提下为您完成翻译。

概览

Solana 以 高吞吐量低延迟 著称。
但如果你在构建:

  • 区块索引器
  • 交易解码器
  • 实时分析
  • 监控或告警系统

你会很快意识到,在 Solana 上流式传输区块 不仅仅是速度问题——更在于如何管理不确定性、数据量以及各种权衡。

本文将阐述:

  1. Solana 区块流式传输的实际工作原理
  2. 主要的流式传输方案
  3. 为何 RPC 延迟会成为瓶颈
  4. 为何提交级别的选择比你想象的更重要

1️⃣ Solana 是基于 Slot,而非基于 Block

重要的后果

  • slot 大约每 ~400 ms 发生一次。
  • 并非每个 slot 都会产生区块
  • 区块可能 延迟到达
  • 确认级别会改变 你收到的数据

因此,当人们谈论 Solana 上的 区块流 时,实际上是在谈论 基于 slot 的执行结果流,具有不同的保证。每种流式方案只是一种处理这种现实的不同方式。

2️⃣ 最基本的方法 – 轮询

# Pseudo‑code
slot = getSlot()
block = getBlock(slot)          # or getParsedBlock(slot)
decodeTransactions(block)

为什么它看起来很有吸引力

  • 简单易懂
  • 没有持久连接
  • 易于原型开发

为什么在大规模时会失效

  • 插槽可能被 跳过
  • 区块可能 尚不存在
  • 重试 频繁
  • RPC 速率限制 很快被触发
  • 大额交易 / 指令数据导致 高延迟

结果: 你最终会构建:

  • 重试循环
  • 回填逻辑
  • 插槽到区块的对账

在低流量时可行;在大规模时则 脆弱且昂贵

3️⃣ blockSubscribe – 事件驱动方式

WebSocket → subscribe (blockSubscribe) → receive blocks pushed from RPC node

优势

  • 减少 RPC 往返次数
  • 相比轮询拥有更低的延迟
  • 流控更简洁

劣势

  • 通常仅限于 confirmed(已确认)和 finalized(已最终确定)提交级别
  • processed 通常 不可用或不可靠
  • 区块仍可能 不完整(缺少部分指令 / 内部指令)
  • 提供商的行为 各不相同

你可以获得 安全性和简易性,但会牺牲 超低延迟

4️⃣ Geyser 插件 – 最强大(也是最复杂)的选项

数据直接 从验证者流式传输,绕过 RPC 瓶颈。

优势

  • 最高的完整性(完整指令可见性)
  • 性能可预测,重试次数极少
  • 延迟极低(接近零)

劣势

  • 需要 验证者访问或合作伙伴关系
  • 基础设施更复杂
  • 运营成本更高

Geyser 并 消除复杂性——它将复杂性转移到应有的基础设施层。

5️⃣ 数据量 – 常被低估的瓶颈

单个 Solana 区块可能包含:

  • 数百甚至数千笔交易
  • 深度嵌套的指令
  • 大型内部指令树
  • 冗长的账户元数据

对基于 RPC 的获取的影响

  • 响应负载很大 → 序列化/反序列化成本高
  • 网络传输主导 端到端延迟

实际情况:

  • getBlock 往往需要 数百毫秒;在负载下可能达到 秒级
  • 重试会放大成本。
  • 即使使用快速解码器,你也常常 在等待网络

典型的轮询循环(简化版)

getSlot()
getBlock()
if missing → retry
if commitment changes → refetch

再加上:

  • 跳过的槽位
  • 部分区块
  • 确认重新检查

结果: 高尾延迟、区块到达不均、管道出现背压,以及 RPC 成本不断上升。
这就是为什么许多 Solana 索引器在测试时 表现快速,但在生产环境中 不稳定

6️⃣ 每个流媒体设置的核心问题

我愿意容忍多大的错误,以及持续多长时间?

Processed Commitment(使用 Geyser)

  • 数据直接来自验证节点的执行路径。
  • processed commitment 在实际使用中 非常常见
  • 延迟 极低;流的稳定性 很高

由于执行数据 立即 发出:

  • 区块 持续 到达。
  • 指令数据 完整
  • 重新处理逻辑 可预测

结果: Geyser + processed 往往是 Solana 上 最快且最稳定 的流媒体设置。适用于:

  • 实时解码
  • 监控系统
  • 低延迟分析
  • 能容忍短暂重组的应用

blockSubscribe – 更安全,但更慢

  • 仅支持 confirmedfinalized
  • 不可靠地暴露 processed
  • 在不同 RPC 提供商之间表现不一。

后果:

  • 端到端延迟更高
  • 重组更少 → 修正逻辑更简单
  • 更安全,但本质上与验证节点级别的流媒体不同

7️⃣ 减少冗余的 RPC 调用

WebSocketGeyser 都能够减少:

  • 冗余的 RPC 调用
  • 轮询开销

但它们 并未改变核心现实

  • 交易 + 指令数据 体积大
  • 解码成本 不可避免
  • 内存压力 真实存在

在 Solana 上,数据大小是 协议设计 的一部分,而非实现细节。

8️⃣ 真实世界实现 – txdecoder.xyz

txdecoder.xyz,我们将 Solana 区块流视为一个 基础设施问题,而不仅仅是 API 选择。

混合流架构

  1. 多个 Geyser gRPC 区块流工作者 – 主要数据源
  2. 额外的 WebSocket blockSubscribe 工作者 – 备用路径

Geyser gRPC

  • 最快的选项
  • 最完整的指令数据
  • 足够稳定,可在 processed 提交级别运行

挑战: 长时间运行的流可能会掉线;验证者可能会重启;网络短暂故障时有发生。

缓解措施:

  • 运行 多个独立的 Geyser 工作者
  • 在下游 去重 区块
  • 将每个工作者视为 非权威来源

收益:

  • 更高的可用性
  • 可预测的延迟
  • 优雅降级而非硬性失败

WebSocket blockSubscribe

  • 在 gRPC 流断开时作为备份
  • 通常运行在 confirmedfinalized(更慢,但在不同提供商之间更具弹性)

目的:

  • 确保 没有长时间的盲区
  • 提供 更平滑的恢复

9️⃣ 要点

方法延迟完整性运维复杂度典型使用场景
轮询 (getSlot → getBlock)高(数百 ms‑秒)部分(取决于提交)低 → 高(重试/回填)原型开发,低流量
blockSubscribe (WebSocket)中等(数十 ms)通常仅已确认/已最终确定中等监控、分析,延迟适中
Geyser (validator‑level)极低(亚 ms)完整(包括 processed高(基础设施,验证者访问)实时解码,超低延迟流水线

最终思考

无论选择哪种方法,理解延迟、完整性和运营开销之间的权衡都是至关重要的。通过将区块流视为基础设施问题并采用混合方法,您可以在保持成本可控的同时实现高可用性低延迟

txdecoder.xyz 团队准备

Source:

验证节点级别中断期间的连续性

在 Solana 上,没有单一的流式方法是完美的。
与其追求一种“理想”的解决方案,我们:

  • 组合多个不完美的流
  • 接受短暂的不一致
  • 在下游以确定性的方式解决它们

这种方法使 txdecoder.xyz 能够:

  • 在正常情况下保持低延迟
  • 在故障时仍保持正确性
  • 避免灾难性的数据缺口

在 Solana 上的弹性是必须自行构建的特性。

Solana 区块流式并非因为 Solana “糟糕”而难。
它之所以困难,是因为 Solana 为以下目标进行优化:

  • 吞吐量
  • 并行执行
  • 低确认延迟

这些选择将复杂性推向了下游。

如果你正在构建 Solana 数据基础设施,你不仅仅是在流式传输区块——你还在管理不确定性、数据量和权衡。没有完美的方法,只有 有意识的 方法。

txdecoder.xyz

交易解码 API – 将以太坊、Base、BSC 和 Solana 上的区块链数据标准化为统一、可读的模式。

网站:

社交与社区:

  • X(Twitter):
  • Telegram:
  • 公告:
  • Medium:
0 浏览
Back to Blog

相关文章

阅读更多 »

了解 secp256k1 与 多签钱包

封面图片:Understanding secp256k1 与 Multisig 钱包 https://media2.dev.to/dynamic/image/width=1000,height=420,fit=cover,gravity=auto,format=auto