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 定义。
绑定过程我建议做成自助服务。消费方在契约目录里点一下「申请绑定」,填写用途、预期数据量、联系人,系统自动审批(或者人工审批,看组织成熟度)。
绑定后,系统会做几件事:
- 在契约里记录消费方信息(就是前面 YAML 里的 consumers 列表)。
- 给提供方发通知:「你的数据被绑定了,别随便改。」
- 启动监控:开始检查数据是否满足 SLAs。
这里有个坑:绑定不是一次性的。消费方可能半年后才开始真正用数据。我建议绑定后设置一个「激活期」,比如 30 天内没有实际数据消费,自动解除绑定,避免契约里挂着一堆僵尸消费者。
3.5 监控:契约的生命线
监控阶段是数据契约体系里最容易被忽视、也最重要的环节。没有监控,契约就是一张废纸。
监控什么?我总结了三层:
| 监控层级 | 检查项 | 告警条件 |
|---|---|---|
| Schema 层 | 字段名、类型、nullable 是否一致 | 任何不一致立即告警 |
| 数据质量层 | 空值率、唯一性、值域范围 | 超过阈值(如空值率 > 5%) |
| SLAs 层 | 数据产出时间、可用性、记录数 | 未在约定时间前产出 |
我个人习惯用 Prometheus + Alertmanager 做监控。每个数据管道在产出数据后,上报一个指标:data_contract_compliance{dataset="user_order_daily", status="compliant"} 1。如果指标没上报或者上报了 0,就触发告警。
核心原则:监控告警要发给提供方和消费方双方。提供方负责修,消费方负责评估影响。别只发给一方,否则容易扯皮。
3.6 废弃:体面地结束
数据契约也有寿终正寝的时候。业务下线、表重构、迁移到新系统,都需要废弃旧契约。
废弃流程我建议分三步:
- 标记废弃:在契约里加一个
status: deprecated字段,同时注明替代契约和废弃原因。 - 通知消费方:给所有绑定的消费方发通知,告知废弃计划和迁移时间窗口。我一般给 30 天缓冲期。
- 强制执行:缓冲期结束后,如果还有消费方没迁移,直接切断数据。听起来很粗暴,但你不这么做,废弃流程永远走不完。
我曾经踩过的坑:有个老系统下线,我发了废弃通知,等了一个月,以为都迁移完了。结果半年后,一个没人维护的报表还在跑,数据源早就没了,报表一直显示空数据。从那以后,我要求废弃契约必须走工单系统,消费方确认迁移后才算完成。
3.7 生命周期全景图
六个阶段串起来,就是一条完整的生命周期。我画了一张图,方便你理解整体流转:
这张图里有个关键设计:监控到定义的反馈回路。监控发现契约被违反,不是直接修监控,而是回到定义阶段重新协商。为什么?因为很多时候是契约定义本身不合理,比如 SLAs 定得太严、schema 设计有缺陷。不改定义只修监控,治标不治本。