ARTICLE · 1214304
继续开源 | 实时数仓开发插件 realtime-data-pipeline 架构和流程说明
昨天开源了离线数开插件。今天开源实时数仓开发插件。
目录
• 一、整体架构[1] • 二、八段执行流程[2] • 三、两种运行模式[3] • 四、适用场景与边界[4] • 五、总结[5] • 仓库地址[6]
离线任务跑完就结束了。实时任务上线才刚开始。
离线可以重跑一批数据,实时更多是在现有流上做变更,变更的影响会立刻传下去。
一条流任务接上消息源以后,会一直消费数据、占用资源、写下游表,也会一直受版本、状态和流量影响。发布、启动、停止、热更新,每一个动作都在改线上状态。写 SQL 只是开头,后面的版本、回读、确认和追踪才是日常。
realtime-data-pipeline 想做的,是把这些动作收进一套有状态、有门控、有证据的流程里。它不替平台执行作业,负责的是让每一步都有明确的输入、证据和出口。
平台仍然是平台,插件只是把动作排好顺序,把证据留下来。
实时开发最容易出错的地方,通常不在 SQL 语法。状态在变,版本在变,上下游也在变。一个人记得住昨天的任务状态,过一周换人接手就未必记得住。插件把这些变化收进状态机和证据账本,让每一次判断都有出处。
一、整体架构
插件可以拆成四层来看。
.rtd/config.json 读取 | |
治理层定规则,工作流层定步骤,执行器层负责真正动手,状态与证据层负责记住发生了什么。
这四层把“流程”和“平台”分开了。插件知道一条实时任务应该怎么走,执行器知道具体该调哪个平台、哪条命令。换引擎、换平台或者换项目,流程本身不用重写。
配置分离还有一个直接好处。仓库里不写平台名、账号和命令,接一个新平台时改的是项目配置,流程文档不用跟着改。团队换环境、换执行器,门控和证据格式仍然一致。
插件不信任模型的自述。编译成功要有编译回执,提交成功要有提交回执,发布完成要有对象回读。高风险动作要有追踪 ID。没有这些,阶段就停在原地。
回读证据和确认证据是两类东西。回读证据来自平台,证明某个动作真的发生了。确认证据来自用户,证明某个高风险动作被授权了。两类证据不能互相顶替,这也是插件和普通脚本最大的区别。
二、八段执行流程
一条实时任务从定位到启动,走的是八个阶段。
discover | ||
design | refs_published | |
build | compile_ok | |
debug | debug_confirmed | |
configure | sla_decided | |
submit | submit_ok | |
publish | publish_ok | |
start | start_confirmed |
discover 和 design 先把对象和来源摸清楚。实时任务只能引用已经发布的元表,开发版存在不算可用。搜索是模糊匹配,表名必须完全相等。来源表查不到时,要先排查项目和权限,不能随手建一张空壳表顶上。
比如一条从消息队列到实时宽表,再供下游报表消费的链路,来源表是不是已发布、字段类型有没有变、任务版本是不是最新、下游有没有被影响,这些问题在开工前就要有答案。discover 和 design 做的就是把这些问题问完,等编译报错再回头猜就晚了。
build 和 debug 解决“能不能跑”和“跑得对不对”。编译失败要看权限、表不存在、语法和项目权限这几类原因。编译通过只说明代码能编译,不说明业务结果正确。调试输出为空时,还要查流量、延迟、过滤条件和窗口设置。
调试也不是随便跑一下。链路验证可以用线上采样,数据验证可以构造输入。采样要看流量和延迟,构造输入要先读服务端的字段,不能凭记忆猜 schema。输出为空时,先查过滤条件、窗口和上游流量,别把空结果当成业务正确。
submit 和 publish 是两个动作。提交后要查发布前校验,发布后要回读待发布对象、版本和平台链接。校验状态还在等待人工确认时,流程要停下来,把链接原样交给用户。
提交、发布、启动是三件不同的事。提交成功只说明平台受理了任务,发布成功要看到对象回读和版本,启动成功要看到运行态。把这三个动作混在一起,最容易出现的情况是任务已经在跑,版本却不是刚审核的那一版。
start 是另一条高风险链路。启动、重启、热更新、停止、下线和取消部署,各自有独立的确认门。启动前要确认对象与环境、动作与版本、恢复点或重置时间、SQL 与计划影响、预计停顿、风险与回退边界。迁移场景还要确认原任务已经停止,恢复点必须由用户给出。
启动前的六项展示不是走形式。对象、版本、恢复点、SQL 影响、停顿和回退边界,任何一项说不清,启动都不该发生。实时任务一旦跑起来,回退成本往往比发布更高。
发布完成以后,插件会自动把本次任务的知识卡写回 knowledge-base-plugin。知识库负责校验、审计、版本化和同步,开发插件只提交任务产物。配置了 GitHub 知识仓库和 OpenViking 时,两边会一起更新,失败不会回滚已经完成的发布。
知识回写只使用本次任务已经确认的产物。它不会把模型临时想出来的口径写进知识库,也不会因为知识库失败回滚发布。
整条流程可以随时查看状态。rtd status 会告诉当前阶段、还缺哪个门、下一步该做什么。跨会话继续时,resume 会先和平台回读对账。
执行记录里留着追踪 ID。超时以后先查原状态,确认平台到底有没有受理,不能因为界面上没返回就再发一次。实时任务的重发成本通常比离线高,重复启动和重复回刷都可能把下游写乱。
三、两种运行模式
auto | |||
manual |
两种模式都要求先选模式、建台账、建目标,再开工。模式选择写进 .rtd/_ledger/preflight.json,Goal 写进 .rtd/_goal.json 和 _goal.md。没有模式或 Goal,阶段推进和高风险动作都会被拒绝。
选择模式看任务风险,不看个人喜好。测试环境、低风险批处理、可以随时回滚的任务,用 auto 更顺。生产首次上线、口径复杂、上下游多、启动会消费真实流量的任务,用 manual 更稳。
auto 只替代逐项人工确认。refs_published、compile_ok、submit_ok、publish_ok 这些证据门仍然逐项检查。启动前还要从 Goal 里读取用户写定的恢复点,读不到就停在 auto_reset_required,不会自动取当前时间。
Goal 要写清楚允许做什么、不允许做什么。auto 不是把权限无限放大,Goal 之外的动作仍然要停下来确认。恢复点也要提前写进 Goal,插件不会替用户取当前时间。
manual 把判断留在每个阶段出口。阶段确认不传递,discover 确认过,design 还要重新确认。高风险动作也要单独确认,安装同意、诊断结论和上一次启动的同意都不算本次授权。
模式选择跟着工单走。隔几天回来,或者换一个人接手,打开状态就能看到当时选了哪种模式、为什么选、目标是什么。模式不靠记忆维持,靠记录维持。
台账只追加,不改历史。谁在什么时候选了哪种模式、为什么选,都能查。
四、适用场景与边界
它适合 Kafka、Flink、Paimon、Doris 这类实时链路的研发和运维。任务多、来源多、上下游关系复杂,或者需要迁移、巡检、诊断、调参和跨人交接的团队,都能用上。
比如业务库 CDC 到实时宽表,再供看板和风控消费。来源表变更、字段口径、任务版本、发布回读、启动恢复点,任何一处出问题,下游看到的都可能是错数。插件把这些检查拆到不同阶段,让开发和运维知道现在该看什么。
迁移老任务时,源任务有没有停、恢复点在哪里、迁移后的版本和原来是否一致,这些都比“迁移命令跑完了”更重要。巡检和诊断则只读平台,不顺手改状态,要改就走另一条带确认的路。
它不适合偶尔写一条临时 SQL 的场景。执行器没有配好时,它只能停在门控和证据这一步。
它不是调度平台,不负责排班、报警和平台可用性。它也不替团队定业务口径,口径本身对不对,仍然要靠人。
它管的是开发动作和发布动作,运行中的稳定性仍然要靠监控和告警。
对使用 AI 协作的团队来说,这套结构有一个实际价值。AI 可以帮忙查表、写 SQL、整理方案和生成命令,但每一步都要留下可以检查的结果。人不用盯着每一行代码,只需要在关键节点看对象、看版本、看证据、看回退边界。
AI 可以快,但快不能替代证据。插件把 AI 的输出放进一个可检查的框里,人只需要在框外看结果。
五、总结
实时数仓最难的地方,是让一条流在正确的时间、正确的版本、正确的状态下上线。晚一步,数据可能已经写进下游;早一步,版本可能还没准备好。
插件把“应该没问题”换成“有编译回执、有发布回读、有追踪 ID”。这句话听起来不热闹,真正上线时却很有用。
如果团队只有一个人、一条任务、一次上线,这套流程可能显得重。任务多、版本多、交接频繁时,它的价值才会显出来,靠记忆维护版本和确认,迟早会出错。
仓库地址
• GitHub MrSuiChuan/realtime-data-pipeline[7] • License Apache-2.0
引用链接
[1] MrSuiChuan/realtime-data-pipeline: https://github.com/MrSuiChuan/realtime-data-pipeline















































































