Contents

数据平台发布流程与环境管理:Dev、Staging、Prod 如何协作

数据平台发布的不只是网页和 API,还可能包括采集连接器、计算任务、数据 Schema、模型权重、标签字典和向量索引。因此,“服务启动成功”远远不等于“发布成功”。一段正常执行的新代码,也可能静默生成错误数据。

环境管理的目标,是让每个版本经过有明确职责的验证,再以可追踪、可停止、可恢复的方式进入生产。下面是一套可按团队规模裁剪的实践方案。

结合 2026-09-06 阅读到的 Data Flywheel 代码,目前已有 SQLite 开发默认配置、Keycloak OIDC 与 PostgreSQL 接入代码,以及本地 Compose 基础设施配置。本文讨论的 Staging、制品晋级、灰度与恢复流程属于后续建设方案,不能将本地服务可启动视为生产发布体系已经完成。

1. Dev、Test、Staging、Prod 分别负责什么

这些环境名没有一套适用于所有公司的强制标准。首先要约定职责,其次才是命名。

环境主要用途数据与资源发布方式
Local个人开发和快速验证小型固定样本、模拟依赖开发者自行运行
Dev多人联调,暴露集成问题独立测试数据,较小配额合并后自动部署较常见
Test / QA功能回归与异常测试可重置数据,覆盖边界情况使用可追踪的候选版本
Staging / Pre-prod上线前演练接近生产拓扑的依赖、代表性脱敏数据部署待发布制品
Prod提供正式服务和生产数据生产数据、生产凭据、正式保障受控发布并持续观察

小团队可以合并 Dev 与 Test,但应保留生产隔离和发布前演练能力。Staging 不一定复制生产全部规模,却应尽量对齐数据库、消息队列、运行时、配置结构和权限机制。开发与生产的差异本身就是故障来源,可参考 Twelve-Factor 的环境一致性原则。

容量测试需要单独考虑:1% 数据上的功能验证,不能证明全量数据下不会内存溢出或造成队列积压。

若运行环境采用 K8s,服务副本、探针、独立迁移步骤与批作业的具体衔接,可继续阅读 Data Flywheel 的 Kubernetes 架构。

2. 环境隔离要覆盖数据链路

只给域名加上 dev- 并不构成环境隔离。至少要检查:

  • 存储:数据库、对象存储路径、向量集合和缓存命名空间是否隔离。
  • 消息:Topic、消费组和死信队列是否分开,测试消费者是否可能确认生产消息。
  • 身份:服务账号、密钥和数据访问范围是否独立,开发凭据不能写生产数据。
  • 计算:GPU、并发、网络和配额是否受控,回填任务是否会抢占在线检索资源。
  • 外部副作用:测试任务是否会误发通知、创建真实标注订单或回调生产系统。

Kubernetes namespace 或目录前缀可以参与隔离,但需要配套身份、网络和存储策略才能形成边界。生产样本进入低环境前,应经过明确授权、必要脱敏和保留期限控制;也可以优先用合成数据与固定回归集。

3. 一次构建,逐级晋级

构建把代码变成制品,发布把制品与环境配置结合,运行阶段启动该发布版本;这三个阶段应明确区分。参见 Twelve-Factor 的 Build、Release、Run。

本文建议:同一个候选制品在 Staging 验证后晋级到 Prod。不要在每个环境重新拉取分支并构建,否则相同代码也可能因依赖变化产生不同结果。

构建门禁可以包含格式与类型检查、相关单元测试、连接器契约测试和镜像依赖检查。发布门禁还要验证数据质量、Schema 兼容性、迁移脚本、权限策略和回滚演练结果。

分支与环境是两个维度。无需为每个环境维护长期业务分支;短分支开发、主分支集成、固定制品晋级也是一种可行方式。环境使用哪个版本,应由部署记录表达。

4. 数据平台的发布单应记录什么

下面是概念性发布清单,字段与标识为示例,不对应特定部署工具:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
release_id: dp-20260906-01
source_commit: "<full-git-commit-sha>"
api_image: "registry.example.com/data-api@sha256:<digest>"
worker_image: "registry.example.com/data-worker@sha256:<digest>"
environment_config_version: prod-config-27
pipeline_version: scene-mining-12
schema_version: clip-v3
tag_dictionary_version: weather-v2
embedding_model_revision: encoder-r17
index_version: scene-index-v8
policy_version: auth-policy-31
migration_plan: migration-208
rollback_plan: rollback-208
owner: data-platform-oncall

凭据本身不写入发布单,只记录密钥引用。配置变化也应该生成新的发布记录,而不是现场修改后失去追踪。

对历史数据重跑,还需要冻结输入快照、时间窗口、模型版本与执行参数。仅保存 Git Commit 无法复现“昨天为什么多挖出了一万条雨天片段”。

5. Schema、任务和索引如何兼容升级

Schema:先扩展,再迁移,最后收缩

以 capture_time 迁移到 captured_at_ms 为例:先增加新字段和兼容读取,再升级写入方,随后限速回填与校验历史数据,最后在确认旧消费者退出后删除旧字段。

双写需要明确哪个字段是权威来源,并监控双写失败和不一致记录。不要在同一次发布中同时删除旧字段、升级全部消费者并重算全部历史数据。

批处理:明确新旧运行的边界

运行中的任务应绑定启动时的版本和配置。新版本负责新任务,旧版本先完成或在检查点停止。不要直接替换运行几小时的作业所依赖的算子代码。

回填作业使用独立任务 ID、目标分区和配额;记录处理进度,失败后能够从已确认的边界恢复。

向量索引:新建、验证、切换

切换 Embedding 模型时,即使向量维度相同,向量空间也可能不兼容。应把模型、预处理、距离度量与索引作为一组版本管理。

一种方案是构建新索引并完成数据追平,在固定检索集上评测,再通过路由或别名切换。查询编码器与索引必须成对切换,旧组合保留一段恢复窗口;具体原子切换能力取决于所用引擎,不能假定所有引擎都支持。

6. 灰度与回滚要检查数据结果

在线 API 可以按租户或流量灰度;批任务可以按数据分区、来源或任务队列灰度。灰度范围应可复现,避免新旧版本同时争抢同一目标分区。

观察维度示例指标异常时的动作
服务稳定性错误率、P95 延迟、超时率停止扩量,恢复旧服务版本
任务运行失败率、积压、处理吞吐暂停新任务,定位失败批次
数据质量完整率、重复率、字段分布隔离输出,禁止下游发布
检索效果固定评测集 Recall@K、人工相关性恢复匹配的旧模型与旧索引
成本每千样本 GPU 时间、存储增量限速并评估是否继续

阈值应在发布前根据基线约定,例如允许的延迟退化比例和最低质量要求。不要等线上变差后才临时决定“是否能接受”。

代码回滚不会撤销已经写入的数据。 恢复方案至少区分三种情况:

  1. 只改变服务行为:回切兼容的制品与配置。
  2. 已产生错误数据:停止下游消费,按血缘和 run ID 定位污染范围,再修复或重跑。
  3. 已执行不可逆迁移:优先评估前向修复;需要恢复备份时,明确数据丢失窗口与服务恢复目标。

7. 让发布成为一份可执行约定

发布前明确负责人、受影响消费者、验证报告、停止条件、恢复步骤与观察窗口。紧急修复可以缩短流程,但仍要保留制品标识、核心验证和恢复记录;线上稳定后补齐回归用例与复盘。

这些流程依赖两类约束:谁能执行生产动作,见 数据平台权限管理;为什么做以及如何验收,见 数据平台需求管理。提交与需求关联方式可参考 Git Commit 提交规范。

流水线如何实现这些约束,继续见 数据平台 CI/CD 技术方案,其中给出了测试分层、制品清单、生产门禁和数据结果发布协议。