Geyser 插件是什么?验证者怎么把数据推给外部系统 图 1
Geyser 插件是什么?验证者怎么把数据推给外部系统 · 图 1

为什么要给验证者”接一根管”

Solana 的官方运维文档对 Geyser 插件的动机写得很直白:验证者承担繁重的 RPC 负载时(例如大量 getProgramAccounts 查询),有可能跟不上网络节奏。问题不在共识,而在出块职责与数据服务职责挤在同一台机器上抢资源。Geyser 的思路是把数据供给从”拉”改成”推”:验证者支持一种插件机制,把账户、时隙、区块、交易的信息实时推送到外部的数据库、消息队列或索引服务,让 RPC 职责从共识关键路径上卸下来。

插件是启动时通过 --geyser-plugin-config 挂进去的,不需要改动验证者代码。接口层面要求插件实现一套生命周期——加载、卸载——和一组数据回调,数据从运行时流经插件,再流向外部系统。

示意图

从接口的回调清单看,Geyser 的输出恰好对应运行时的状态变化:账户更新、时隙状态、区块完成、交易状态迁移。账户更新回调带一个 is_startup 标志,用来区分”验证者启动时从快照装载账户”与”交易处理过程中账户被更新”两种情形——对下游索引器来说,前者是全量追赶,后者是增量事件,混在一起账就乱了。

交易状态的通知是两段式的:交易被处理时验证者先通知一次,跨过更高的承诺档位时再通知一次。下游因此可以做”先猜测、后确认”的两段视图,不必靠轮询去追交易到底算不算数。这与 RPC 端 processed、confirmed、finalized 三档承诺是同一套语言,只是推送方向反了过来。

gRPC 只是最常见的出水口

Geyser 本身不做网络传输,它是验证者进程内的接口;数据怎么出去是具体插件的事。最出名的下游是 Yellowstone 系列 gRPC 服务:基于 Geyser 提供时隙、区块、交易、账户更新的订阅通道,支持按账户列表、成功与否、是否含投票交易等条件过滤,多个条件之间是逻辑与,同一条件的列表内是逻辑或。它的说明文档也明确列了已知限制:区块更新事件本身不携带完整的交易与账户明细,完整区块要靠在内存里按序收集消息重建,重建失败会被计入指标。

这带来一个重要的判断口径:Geyser 解决的是数据流出,不是数据可信。你收到的仍然是那个验证者节点的视角,承诺档位、重组回退、最终性规则都得自己处理,换数据来源不等于换信任模型。

运维的另一面

插件机制的收益要连着代价一起算。插件动态加载、在验证者进程内执行,回调里做重活或者队列阻塞,拖累的是节点主路径,所以生产级的下游普遍强调背压、限流和重连。订阅通道还要处理心跳:中间层的负载均衡会掐掉长时间没有客户端消息的连接,需要定期发 ping 保活,这一条在 gRPC 插件的说明里专门写了。重启之后的追赶阶段,事件是否齐全、顺序如何,取决于插件与下游各自的实现约定。

普通项目一般不需要自己搭这条管道,托管的流式订阅服务已经成熟,多家供应商按不同档位卖这类通道。但懂管道结构能回答几个常见问题:为什么不同数据商报出的延迟不一样(推送通道与轮询 RPC 的差别);为什么账户索引偶尔整批重播(快照装载的全量阶段);为什么”交易进系统了链上却查不到”(收到了处理通知,还没跨过确认档位)。还有一类事故也出在这里:索引器崩溃后重连,若没有按编号或时隙做缺口回补,漏掉的窗口不会自己补回来——缺口检测要下游自己做,这是接管道方的责任而不是水龙头的义务。水源头在验证者进程边缘,下游稳不稳取决于管道怎么修、缺口怎么补、口径怎么对。本文是机制说明,不构成任何投资建议。