Polkadot RPC 延迟主要由 Substrate 的状态访问模式、网络地理位置和端点饱和决定。本指南解释了数据路径,提供了可重复的测量方法,并给出了优化策略。
什么决定了 Polkadot RPC 延迟?
Polkadot RPC 延迟是发送 JSON-RPC 请求到 Polkadot 节点和接收响应之间的时间。与 EVM 链上大多数调用命中简单的账户余额或存储槽不同,Polkadot 运行在 Substrate 上,这引入了不同的数据路径:状态存储在 Patricia Merkle 树中,许多 RPC 方法(如 state_getStorage)需要遍历该树。中继链还使用 GRANDPA 最终性,因此您查询的“最新”区块可能是软区块头,尚未最终确定。
主要因素包括:(1)客户端与节点之间的物理距离,(2)节点的存储类型(归档节点与修剪节点),(3)共享端点上的负载,以及(4)客户端库(例如 polkadot.js 与原始 JSON-RPC)的效率。本文解释了 Substrate 特有的机制,为您提供了可重复的测量方法,并列出了优化策略。
- Substrate 状态 RPC 方法(
state_getStorage、state_getPairs、state_queryStorage)比 EVM 链上的简单eth_getBalance更重。 - GRANDPA 最终性意味着您可以查询尚未最终确定的区块;最终性滞后会影响一致性。
- 归档节点保留所有历史状态,使深度查询更慢但可行;修剪节点仅提供近期状态。
- WebSocket 连接有握手开销,重连风暴可能看起来像延迟峰值。
Substrate 数据路径:为什么 Polkadot RPC 不同
Polkadot 的中继链基于 Substrate 构建,所有状态都存储在树中。当您使用存储键调用 state_getStorage 时,节点必须从根到叶遍历树,从数据库读取节点。这比读取平面键值存储更耗费 I/O。树的深度随条目数量增长,因此对大型映射(如验证人集合)的查询可能更慢。
此外,Substrate 暴露了运行时 API 调用(例如 state_call 调用运行时方法),这些调用可能执行复杂逻辑。这些不是简单的读取;它们在 Wasm 环境中运行,可能需要更长时间。polkadot.js API 经常在底层使用这些,因此您可能会看到比原始 chain_getBlock 调用更高的延迟。
区块最终性:Polkadot 使用 GRANDPA 实现最终性,它落后于最佳区块。当您查询 chain_getHeader 而不指定区块哈希时,您会得到最佳区块,它可能未最终确定。如果您需要最终确定的状态,必须指定最终确定的区块哈希,这增加了查找步骤。这在 Polkadot JSON-RPC 文档 和 Substrate RPC 文档 中有记录。
- 状态树遍历增加了与树深度和数据库读取时间成比例的延迟。
- 运行时 API 调用(
state_call)比简单的存储读取更昂贵。 - 最终性滞后:“最新”区块不一定最终确定;使用
finalized_head保持一致性。 - 归档节点存储所有历史状态,因此查询旧区块是可能的但更慢;修剪节点对旧状态返回错误。
测量 Polkadot RPC 延迟:可重复的方法
要准确测量延迟,您需要将网络往返时间与节点处理时间分开。以下方法使用 curl 进行 HTTP 测试,使用 Node.js 脚本进行 WebSocket 测试。它测量 system_chain、chain_getBlock、state_getStorage 以及 WebSocket 连接/握手。从您自己的基础设施运行以获得与您位置相关的数字。结果由读者运行,而非供应商基准。
先决条件:curl、websocat(或 Node.js 脚本)以及 Polkadot RPC 端点。您可以使用公共端点或自己的节点。为了可重复的结果,运行多次迭代并计算 p50/p95。
- 使用
curl -w捕获 HTTP 请求的计时细节。 - 对于 WebSocket,使用带有
ws包的 Node.js 脚本测量连接和请求延迟。 - 至少运行 10 次迭代以获得有意义的百分位数。
- 记录端点 URL、日期和您的地理位置以供参考。
#!/bin/bash
# HTTP 延迟测试 Polkadot RPC
ENDPOINT="https://rpc.polkadot.io"
for i in {1..10}; do
curl -s -o /dev/null -w "%{time_total}\n" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"system_chain","params":[],"id":1}' \
$ENDPOINT
done
# 预期输出:10 个数字(秒),例如 0.234, 0.198, ...WebSocket 延迟与重连影响
WebSocket 是 polkadot.js 的默认选择,因为它支持订阅。然而,WebSocket 连接有一个握手(HTTP 升级),这会在第一个请求上增加延迟。后续请求共享连接,因此每个请求的延迟较低。但如果连接断开,客户端会重新连接,重新公告(重新订阅所有活动订阅)可能导致请求突发,看起来像延迟峰值。
在测量 WebSocket 延迟时,将连接时间与请求时间分开。使用一个脚本连接一次,然后计时各个请求。另外,请注意 polkadot.js 可能批处理请求或使用订阅,这会影响感知延迟。
- 握手为第一个请求增加约 1 个 RTT。
- 重连触发重新订阅,可能导致临时负载。
- 每次订阅后使用
unsub避免过时订阅。 - 对于一次性查询,HTTP 可能更简单、更快。
// Node.js WebSocket 延迟测试(需要 'ws' 包)
const WebSocket = require('ws');
const ws = new WebSocket('wss://rpc.polkadot.io');
let id = 0;
const t0 = Date.now();
ws.on('open', () => {
console.log('连接时间 (ms):', Date.now() - t0);
for (let i = 0; i < 10; i++) {
const start = Date.now();
ws.send(JSON.stringify({jsonrpc:'2.0', method:'system_chain', params:[], id:++id}));
ws.on('message', (data) => {
const msg = JSON.parse(data);
if (msg.id === id) {
console.log('请求', id, '延迟 (ms):', Date.now() - start);
}
});
}
});
// 预期输出:连接时间和每个请求的延迟。常见故障与修复
在测量或使用 Polkadot RPC 时,您可能会遇到超时、速率限制或过时数据。以下是常见问题及解决方法。
如果您在 state_getStorage 上对旧区块超时,您的节点可能已被修剪。使用归档端点或指定近期区块。如果您被限流,请降低请求频率或使用专用端点。如果您看到不一致的结果,请检查您是否查询了最终确定的区块。
- 历史状态超时:使用归档节点或查询近期区块。
- 速率限制:实现退避或使用专用端点(参见 Polkadot RPC 速率限制)。
- WebSocket 断开:使用指数退避实现重连,并小心重新订阅。
- 共享端点的高延迟:考虑地理分布式提供商或专用节点。
- polkadot.js 订阅泄漏:使用后务必调用
unsub。
优化策略
为了减少 Polkadot RPC 延迟,请关注以下方面:端点选择、客户端效率和查询设计。
端点选择:选择节点靠近您的用户或后端的提供商。像 OnFinality 的 API 服务 这样的地理分布式提供商将请求路由到最近的节点。避免公共端点,因为它们共享严重;在负载下它们可能有更高的延迟。
客户端:高效使用 polkadot.js。最小化订阅,每次使用后 unsub,并在可能的情况下批处理请求。对于一次性查询,使用原始 JSON-RPC over HTTP 以避免 WebSocket 开销。缓存不经常变化的状态。
查询设计:使用特定前缀缩小 state_getPairs 以减少数据传输。仅在必要时使用 state_queryStorage 进行历史查询。如果您需要完整区块,优先使用 chain_getBlock 而不是 chain_getBlockHash。
- 使用地理分布式端点或专用节点。
- 保持 polkadot.js 订阅最少并始终取消订阅。
- 在 SDK 允许的情况下批处理请求(例如
api.queryMulti)。 - 缓存频繁访问的状态(例如运行时版本、常量)。
- 缩小存储键前缀以减少响应大小。
- 选择 WebSocket 用于订阅,HTTP 用于一次性调用。
权衡与限制
优化延迟通常涉及权衡。归档节点提供完整的历史数据,但更慢且更昂贵。修剪节点更快,但仅限于近期状态。使用专用端点减少争用,但成本更高。批处理请求减少往返,但可能增加批处理的响应时间。
测量本身有局限性:网络条件变化,您的结果取决于您的位置和端点的负载。始终记录您的方法并运行多次测试。像 CompareNodes 这样的独立基准测试提供他们自己的方法;将它们视为参考,而不是您自己的测量。
- 归档与修剪:归档对于深层历史是必要的,但更慢。
- 专用与共享:专用提供一致的延迟,但成本更高。
- 批处理:减少开销,但可能延迟单个响应。
- 测量差异:在不同时间和不同位置运行测试。
后续步骤
既然您了解了 Polkadot RPC 延迟,您可以将这些技术应用到自己的基础设施中。有关更多详细信息,请探索以下资源:
从 Polkadot 网络概述 开始了解架构。然后深入了解 Polkadot WebSocket RPC 指南 以了解连接最佳实践。如果您遇到限制,请阅读 Polkadot RPC 超时和重试 和 Polkadot RPC 速率限制。对于端点选择,请参阅 Polkadot RPC 端点(RPC 助手) 并考虑 RPC 定价 以获取专用选项。最后,探索 OnFinality Learn 中心 获取更多指南。