建设数据平台时,最常见的误区之一,是把目标描述成一张完整技术栈:
MinIO + PostgreSQL + dbt + Dagster + Metabase + CI/CD这张清单只能说明系统准备使用什么,却没有回答:
- 为什么需要这些组件;
- 每个组件解决什么问题;
- 为什么现在引入;
- 如果不引入会发生什么;
- 什么条件下需要重新选择。
技术越多,不代表架构越成熟。过早引入暂时不需要的组件,反而会让团队先承担部署、集成和运维成本,却迟迟不能证明数据产品是否正确。
因此,当前项目的技术选择遵循一个基本原则:
先验证最关键、最不确定的机制,再引入支撑这些机制长期运行的基础设施。
总说
可信销售DataOps Lab分三个阶段建设:
第一阶段:证明数据是正确的 PostgreSQL + dbt + 候选/可信发布 第二阶段:证明数据能够稳定生产和恢复 MinIO + Dagster 第三阶段:证明数据真正可以被消费 Metabase批处理贯穿当前阶段,因为核心数据产品是日销售表现,日级处理已经满足业务时效。
每项技术的引入都必须回答:
它解决什么当前问题 → 为什么现阶段需要 → 增加什么复杂度 → 什么情况下重新评估一、第一阶段:先证明数据正确
第一阶段最重要的风险,不是系统能否处理海量数据,而是:
- 净收入等指标是否定义正确;
- 输入异常能否被识别;
- 重复运行是否产生重复结果;
- 质量失败是否会污染消费数据;
- 结果能否通过固定样例验证。
因此,首个纵向切片只需要完成:
确定性输入 → 数据摄取 → SQL转换 → 质量检查 → 可信发布这一阶段选择PostgreSQL、dbt和候选/可信发布机制。
1. 为什么采用批处理
核心数据产品是日销售表现,消费者按日查看销售额、退款额和净收入。
当前没有秒级更新或盘中自动决策需求。因此,实时流处理不会改变业务行动,却会增加:
- 消息顺序;
- 重复消费;
- 迟到事件;
- 状态恢复;
- 消息重放;
- 流平台运维。
批处理可以使用batch_id作为明确边界:
生成一个批次 → 完整校验 → 整批转换 → 整批发布它更容易验证幂等、重跑、回填和故障恢复,符合当前项目重点。
这不是团队缺少实时能力,而是当前业务价值不足以支撑实时复杂度。
重新评估批处理的条件包括:
- 数据产品开始支持盘中决策;
- 数据频率提升到分钟或逐笔;
- 日批无法在消费时间前完成;
- 消费者能从更低延迟中获得明确收益。
2. 为什么使用PostgreSQL
当前数据规模小,核心模型主要通过关系运算和SQL完成,包括:
- 订单、支付和退款关联;
- 业务键去重;
- 金额聚合;
- 日销售指标计算;
- 候选结果和发布记录管理。
PostgreSQL的主要优势不是性能极限,而是:
- 事务能力成熟;
- SQL表达能力完整;
- 约束和索引清晰;
- Python、dbt和BI工具兼容良好;
- 团队容易理解和维护;
- 本地环境容易复现。
尤其是可信发布需要在一个事务中完成:
验证候选版本 → 更新可信结果 → 登记发布记录 → 一起提交或一起回滚PostgreSQL能够以较低复杂度提供这一保证。
当前没有选择分布式仓库或湖仓引擎,是因为数据规模和并发尚未形成瓶颈。提前采用它们只会增加部署和运维成本。
重新评估PostgreSQL的条件包括:
- 数据规模持续超出单机处理能力;
- 日批无法在时效目标内完成;
- 并发研究和分析查询成为稳定瓶颈;
- 数据类型和工作负载明显不适合关系数据库。
3. 为什么使用dbt
当前大部分数据转换都可以用SQL清晰表达。真正需要解决的问题不是“怎样执行SQL”,而是怎样管理SQL模型之间的关系。
dbt提供了四项关键能力:
模型依赖 + 数据测试 + 文档 + 血缘它使暂存、核心和消费模型能够形成显式依赖,并把质量检查放到数据模型附近。
例如:
raw.orders → stg_orders → core_order_finance → candidate.daily_sales订单主键唯一性、支付引用完整性和金额边界等规则,可以随模型一起维护和执行。
使用dbt还有一个重要的责任边界:
- dbt负责数据转换和模型测试;
- Dagster负责运行顺序和依赖协调;
- PostgreSQL负责数据存储和事务;
- Python负责输入契约和发布控制。
净收入公式不应写在Dagster任务中,否则业务逻辑会与编排工具绑定。将SQL转换保留在dbt中,未来替换编排器时不需要迁移指标逻辑。
重新评估dbt的条件包括:
- 核心计算大量超出SQL表达能力;
- 系统转向复杂流式状态处理;
- 目标计算引擎无法合理支持dbt;
- 转换逻辑更适合专门的计算框架。
4. 为什么采用候选/可信发布
如果转换结果直接覆盖消费表,会产生一个危险问题:
数据已经写入,但质量检查还没有完成。
一旦新批次存在重复订单、退款缺失或指标错误,消费者会立刻看到错误结果。
因此,项目将计算和发布拆开:
构建候选版本 → 执行质量检查 → 作出发布决定 → 更新可信版本候选数据是可以丢弃和重建的中间结果;可信数据则是明确允许消费者使用的版本。
这一机制保证:
- 计算成功不等于发布成功;
- 质量失败不能污染消费结果;
- 发布失败不会留下半完成状态;
- 最近一次可信版本始终可用;
- 每次发布都有独立证据。
重新评估这一机制的条件,不是简单地“数据量变大”,而是发布模型发生变化。例如转向事件级实时决策后,可能需要更细粒度的版本、流式质量判断或增量发布机制。
二、第二阶段:再证明数据能够稳定运行
第一阶段证明的是业务逻辑、质量规则和发布机制正确。
但它还没有完整解决:
- 原始输入如何长期保存;
- 上游补发或修订后怎样重放;
- 多步骤任务怎样协调;
- 失败后怎样自动重试和回填;
- 每次运行怎样留下完整证据。
这些问题在机制尚未验证时不是首要风险,因此MinIO和Dagster放到第二阶段。
1. 为什么分阶段引入MinIO
一期可以使用确定性本地文件完成输入和质量验证,不需要立即部署对象存储。
当系统进入稳定运行阶段后,需要保存:
- 不可变原始文件;
- 批次清单;
- 输入指纹;
- 来源版本;
- 失败样本;
- 历史回填输入。
这时MinIO开始产生明确价值。
它在本地提供兼容对象存储的接口,使项目能够模拟生产环境中的原始数据层,同时避免一开始引入公有云依赖。
MinIO的主要责任是保存来源证据,不负责业务转换。
原始输入 → MinIO不可变对象 → 批次登记 → PostgreSQL摄取和转换如果项目一开始就部署MinIO,团队需要同时处理容器、账户、存储桶、权限和网络配置,而这些工作不能证明净收入是否正确。
因此,MinIO是在数据产品闭环成立后,为可追溯和重放能力服务。
重新评估MinIO的条件包括:
- 项目迁移到公有云对象存储;
- 数据规模和可靠性要求超过单机部署能力;
- 需要跨区域复制或更完整的生命周期管理;
- 对象存储不再只是实验环境组件。
2. 为什么分阶段引入Dagster
首个纵向切片的任务数量有限,可以通过统一命令按固定顺序运行。此时主要目标是验证每个步骤本身是否正确。
当流程扩展到以下能力时,编排器才开始产生明显价值:
- 等待多个输入到齐;
- 管理步骤依赖;
- 记录每次运行;
- 失败后有限重试;
- 按日期范围回填;
- 监控超时和数据未到;
- 协调MinIO、PostgreSQL和dbt。
Dagster负责:
什么时候运行 → 依赖是否满足 → 哪一步失败 → 是否允许重试 → 怎样触发回填它不负责:
净收入如何定义 哪些质量问题必须阻断 什么候选版本可以发布后面这些属于业务规则和发布规则。
分阶段引入Dagster还有一个好处:在没有编排器时先把业务逻辑做成独立、可测试的命令,可以避免逻辑被藏在Dagster任务内部。
重新评估Dagster的条件包括:
- 工作流规模和团队协作方式发生明显变化;
- 项目转向持续流处理;
- 编排运行成本超过它带来的收益;
- 需要平台现阶段无法提供的多租户或资源治理能力。
三、第三阶段:最后证明数据能够被正确消费
数据生产链路稳定后,项目才引入Metabase。
这不是因为展示不重要,而是因为展示依赖上游已经形成可信语义。
1. 为什么不提前建设仪表盘
如果指标定义、质量规则和发布机制尚未稳定,提前建设仪表盘会产生两个问题。
第一,团队会把注意力放在图表和样式上,却没有证明数据是否正确。
第二,业务逻辑容易进入展示层。例如,净收入可能被直接写成Metabase中的临时公式,造成同一指标在数据库和仪表盘中存在两个定义。
所以,正确顺序是:
固定指标定义 → 建立候选/可信发布 → 输出数据健康状态 → 再接入仪表盘2. 为什么选择Metabase
当前项目需要的是轻量消费入口,而不是建设完整分析平台。
Metabase能够:
- 连接PostgreSQL;
- 快速制作销售仪表盘;
- 展示数据日期和健康状态;
- 支持基本筛选和下钻;
- 降低本地作品集的部署成本。
Metabase只能读取可信发布层,不能直接查询原始层和候选层。
核心指标也不能在Metabase中重新实现。它负责展示,不负责决定业务语义。
重新评估Metabase的条件包括:
- 消费者规模和并发明显增长;
- 需要复杂的权限隔离;
- 需要嵌入业务应用;
- 需要更完整的语义层;
- 现有查询性能无法满足交互要求。
四、完整的技术决策链
整个技术栈不是并列组件,而是一组按风险顺序引入的能力。
| 阶段 | 主要风险 | 技术与机制 |
|---|---|---|
| 第一阶段 | 指标错误、质量失败污染消费数据 | 批处理、PostgreSQL、dbt、候选/可信发布 |
| 第二阶段 | 原始证据丢失、运行失败无法恢复 | MinIO、Dagster |
| 第三阶段 | 数据无法被消费或被错误解释 | Metabase |
对应的建设顺序是:
先证明结果正确 → 再证明运行可靠 → 最后证明消费有效这种顺序避免了两个极端:
- 只做SQL和表,没有运行与恢复能力;
- 先建设完整平台,却没有可信数据产品。
五、怎样记录这些决策
这些结论不应只存在于架构文章中,还应保存为轻量ADR:
ADR-001:采用批处理而不是实时流处理 ADR-002:采用PostgreSQL作为一期仓库 ADR-003:采用dbt管理转换与模型测试 ADR-004:采用候选—可信发布机制 ADR-005:在可靠运行阶段引入MinIO ADR-006:在工作流复杂化后引入Dagster ADR-007:在可信闭环后引入Metabase每份ADR至少回答:
当前问题是什么 → 有哪些候选方案 → 为什么选择当前方案 → 接受了什么代价 → 什么条件下重新评估例如,“采用批处理”不是永久拒绝实时系统,而是在当前日级消费场景下,选择能够以更低复杂度满足时效要求的方案。
当消费场景变成盘中决策时,原决策条件发生变化,就应该重新评估。
结语
当前技术栈的核心逻辑,不是把常见数据工具组合在一起,而是按项目风险逐步增加能力:
PostgreSQL和dbt证明数据能够正确产生 → 候选/可信发布保护消费结果 → MinIO保存原始证据 → Dagster保证流程可协调和恢复 → Metabase让可信数据真正被使用每项技术只在它解决的矛盾成为当前主要问题时引入。
这套决策可以概括为:
先用最简单的方案证明数据价值,再为已被证明的价值增加可靠性、可追溯性和消费能力。
因此,暂不建设实时流处理、暂不引入完整对象存储和编排,并不是能力不足,而是在业务价值、团队能力、工程复杂度和未来可逆性之间作出的主动取舍。