3. 数据契约的生命周期:定义、发布、发现、绑定、监控、废弃

数据契约不是写一份文档就完事了。它跟软件一样,有自己的生命周期。我见过太多团队把契约当成「一次性交付物」,签完就扔进 wiki 吃灰。结果呢?半年后数据变了,没人通知,下游全崩了。

这一章,我们把这六个阶段拆开揉碎。每个阶段该做什么、不该做什么,我都会结合踩过的坑来讲。

3.1 定义:把口头约定变成机器可读的契约

定义阶段是起点。说白了,就是让数据提供方和消费方坐在一起,把「我给你什么数据、长什么样、多久更新一次」这些事写清楚。

我个人习惯用 YAML 写契约定义。为什么?因为 JSON 太啰嗦,XML 更不用提。YAML 可读性好,还能直接进 Git 做版本管理。

一个典型的数据契约定义(YAML 格式):

version: "1.0"
dataset: "user_order_daily"
provider: "order_service"
owner: "team-order@company.com"

schema:
  - name: user_id
    type: string
    description: "用户唯一标识"
    nullable: false
  - name: order_count
    type: integer
    description: "当日订单数"
    nullable: false
  - name: total_amount
    type: decimal(10,2)
    description: "当日订单总金额"
    nullable: true

slas:
  freshness: "T+1 08:00 UTC"
  availability: "99.9%"
  min_records: 100000

consumers:
  - team: "bi_team"
    purpose: "日活报表"
  - team: "recommendation"
    purpose: "用户画像更新"

注意几个关键点:

  • owner 字段必须填人,不是团队别名。我在项目中遇到过团队别名半年换了三个人,出问题找不到人。
  • nullable 要明确。很多坑都是因为提供方觉得「这个字段不会为空」,结果某天业务异常,空值灌进来,下游直接报错。
  • SLAs 要量化。「尽快更新」这种话别写,写「T+1 08:00 UTC」。

3.2 发布:让契约可以被发现

定义写好了,存在哪里?发邮件?扔共享文件夹?别闹了。

发布阶段的核心是注册到契约中心。我建议用 Git 仓库 + CI/CD 流水线的方式。每次契约变更,提交 PR,review 通过后自动注册到元数据中心。

我的做法:用 GitLab/GitHub 做契约仓库,MR 模板里强制填写变更原因、影响范围、兼容性检查结果。合并后触发 webhook,自动更新内部契约注册表。

发布时还要做一件事:版本化。契约版本号建议遵循语义化版本:

版本号 变更类型 示例
MAJOR 不兼容变更 删除字段、修改字段类型
MINOR 向后兼容新增 新增可选字段
PATCH 描述性变更 修改 description、修复 typo

为什么要这么严格?我曾经在一个项目里,数据提供方悄悄把字段类型从 int 改成 string,没改版本号。下游 BI 系统直接解析失败,报表停了半天。从那以后,我要求所有契约变更必须过版本号检查。

3.3 发现:消费方怎么找到契约

契约发布了,消费方不知道,等于白干。发现阶段解决的是「我怎么知道有哪些数据可用」的问题。

我建议搭建一个契约目录。可以简单点,用内部 Wiki 页面自动同步;也可以上正经的元数据平台,比如 Apache Atlas、Amundsen 或者 DataHub。

发现机制要支持两种场景:

  • 主动搜索:消费方按数据集名称、标签、owner 搜索契约。
  • 被动通知:消费方订阅某个数据域,当有新契约发布或现有契约变更时,自动收到通知。

注意:发现阶段最容易出现的问题是「契约目录和实际数据不一致」。我建议每天跑一次校验任务,对比契约定义和实际数据源的 schema,不一致就告警。

3.4 绑定:消费方确认使用

绑定是契约生效的起点。消费方找到契约后,需要显式地「绑定」——也就是确认:我要用这个数据,我接受契约里的 SLAs 和 schema 定义。

绑定过程我建议做成自助服务。消费方在契约目录里点一下「申请绑定」,填写用途、预期数据量、联系人,系统自动审批(或者人工审批,看组织成熟度)。

绑定后,系统会做几件事:

  1. 在契约里记录消费方信息(就是前面 YAML 里的 consumers 列表)。
  2. 给提供方发通知:「你的数据被绑定了,别随便改。」
  3. 启动监控:开始检查数据是否满足 SLAs。

这里有个坑:绑定不是一次性的。消费方可能半年后才开始真正用数据。我建议绑定后设置一个「激活期」,比如 30 天内没有实际数据消费,自动解除绑定,避免契约里挂着一堆僵尸消费者。

3.5 监控:契约的生命线

监控阶段是数据契约体系里最容易被忽视、也最重要的环节。没有监控,契约就是一张废纸。

监控什么?我总结了三层:

监控层级 检查项 告警条件
Schema 层 字段名、类型、nullable 是否一致 任何不一致立即告警
数据质量层 空值率、唯一性、值域范围 超过阈值(如空值率 > 5%)
SLAs 层 数据产出时间、可用性、记录数 未在约定时间前产出

我个人习惯用 Prometheus + Alertmanager 做监控。每个数据管道在产出数据后,上报一个指标:data_contract_compliance{dataset="user_order_daily", status="compliant"} 1。如果指标没上报或者上报了 0,就触发告警。

核心原则:监控告警要发给提供方和消费方双方。提供方负责修,消费方负责评估影响。别只发给一方,否则容易扯皮。

3.6 废弃:体面地结束

数据契约也有寿终正寝的时候。业务下线、表重构、迁移到新系统,都需要废弃旧契约。

废弃流程我建议分三步:

  1. 标记废弃:在契约里加一个 status: deprecated 字段,同时注明替代契约和废弃原因。
  2. 通知消费方:给所有绑定的消费方发通知,告知废弃计划和迁移时间窗口。我一般给 30 天缓冲期。
  3. 强制执行:缓冲期结束后,如果还有消费方没迁移,直接切断数据。听起来很粗暴,但你不这么做,废弃流程永远走不完。

我曾经踩过的坑:有个老系统下线,我发了废弃通知,等了一个月,以为都迁移完了。结果半年后,一个没人维护的报表还在跑,数据源早就没了,报表一直显示空数据。从那以后,我要求废弃契约必须走工单系统,消费方确认迁移后才算完成。

3.7 生命周期全景图

六个阶段串起来,就是一条完整的生命周期。我画了一张图,方便你理解整体流转:

数据契约生命周期全景图 定义 发布 发现 绑定 监控 废弃 监控发现异常 → 重新定义 关键说明: • 定义 → 发布 → 发现 → 绑定 → 监控 → 废弃,按顺序执行。 • 监控阶段如果发现契约被违反,需要回到定义阶段重新协商。 • 废弃不是终点,废弃的契约应保留历史记录,供审计和回溯使用。 各阶段产出物: 定义 → 契约 YAML 文件(Git 仓库) 发布 → 注册到契约中心 + 版本标签 发现 → 契约目录 / 元数据平台 绑定 → 消费方确认记录 + 监控规则 监控 → 合规指标 + 告警规则 废弃 → 废弃标记 + 迁移计划 + 历史归档

这张图里有个关键设计:监控到定义的反馈回路。监控发现契约被违反,不是直接修监控,而是回到定义阶段重新协商。为什么?因为很多时候是契约定义本身不合理,比如 SLAs 定得太严、schema 设计有缺陷。不改定义只修监控,治标不治本。