4、数据契约的生命周期:设计、发布、发现、绑定、消费、废弃
数据契约不是写一份文档就完事了。它有自己的生命轨迹,从设计到废弃,每一步都有坑。我见过太多团队把契约当摆设,签完就扔一边,结果数据一跑就崩。
说白了,数据契约的生命周期就是六个阶段:设计 → 发布 → 发现 → 绑定 → 消费 → 废弃。每个阶段都有明确的输入输出,也有对应的工具和规范。
核心观点:数据契约的生命周期必须可追溯、可审计、可自动化。手动维护的契约,迟早会腐烂。
4.1 设计阶段:打好地基
设计阶段是契约的起点。我个人习惯先画数据流图,再写 Schema。别一上来就写 JSON Schema 或 Protobuf,先搞清楚数据从哪里来、到哪里去、中间经过哪些转换。
设计阶段要回答三个问题:
- 数据是什么?——字段名、类型、长度、枚举值
- 数据怎么来?——生产者是谁、采集方式、频率
- 数据怎么用?——消费者是谁、使用场景、SLA 要求
我的经验:设计阶段最容易犯的错误是「过度设计」。我曾经见过一个团队给日志数据设计了 200 个字段的契约,结果实际只用到了 15 个。契约不是越全越好,够用就行。
设计阶段的输出物通常包括:
| 产出物 | 说明 | 示例 |
|---|---|---|
| Schema 定义 | 字段结构、类型、约束 | Avro / Protobuf / JSON Schema |
| 数据字典 | 字段含义、取值范围 | Markdown 文档或 Wiki |
| 示例数据 | 正常数据 + 边界数据 | JSON 文件或代码注释 |
| 校验规则 | 非空、唯一、范围、格式 | 正则表达式或断言脚本 |
4.2 发布阶段:让契约生效
设计好的契约要发布出去,才能被其他人发现和使用。发布不是扔到 Git 仓库就完事了——你想想看,如果消费者不知道你更新了契约,他们还在用旧版本,数据能不出问题吗?
我建议用契约注册中心来管理发布。注册中心可以是一个独立的服务,也可以基于已有的 Schema Registry(比如 Confluent Schema Registry)来扩展。
发布阶段的关键动作:
- 版本化——每次变更都生成新版本,旧版本保留可追溯
- 兼容性检查——向后兼容?向前兼容?还是完全兼容?
- 元数据注册——生产者、消费者、数据源、SLA 等信息一并注册
- 通知——通知已绑定的消费者有新版可用
注意:发布阶段的兼容性检查是重中之重。我曾经遇到过因为改了字段类型(int → string)导致下游消费服务全部崩溃的事故。从那以后,我强制要求所有契约变更必须通过兼容性检查才能发布。
4.3 发现阶段:让消费者找到契约
契约发布之后,消费者怎么找到它?这就是发现阶段要解决的问题。说白了,你需要一个契约目录,让消费者可以搜索、浏览、订阅。
发现阶段的常见实现方式:
- API 网关——通过注册中心暴露查询接口
- 数据目录工具——比如 Apache Atlas、Amundsen
- 内部开发者门户——自建或基于 Backstage
- 代码仓库——通过标签和 README 组织
我个人比较推荐用标签 + 分类的方式来组织契约。比如按数据域(用户、订单、支付)、按重要程度(核心、普通、临时)、按数据源类型(MySQL、Kafka、HDFS)来打标签。这样消费者搜索起来效率高很多。
4.4 绑定阶段:建立消费关系
绑定阶段是契约从「存在」到「被使用」的关键一步。消费者找到契约后,需要订阅这个契约,并建立校验规则。
绑定阶段要做的事情:
- 消费者注册——记录谁在使用这个契约
- 校验规则映射——把契约中的约束映射到实际消费逻辑中
- SLA 确认——数据延迟、可用性、准确性等指标
- 告警配置——数据异常时通知谁、怎么通知
关键点:绑定阶段一定要记录消费者的联系方式。我见过太多团队在数据出问题后找不到负责人,只能靠猜。绑定的时候就把钉钉群、企业、邮箱等信息登记好。
4.5 消费阶段:真正跑起来
消费阶段是契约发挥价值的地方。数据生产者按照契约生产数据,消费者按照契约消费数据,中间有实时校验来保证一致性。
消费阶段的校验策略:
| 校验类型 | 触发时机 | 处理方式 |
|---|---|---|
| Schema 校验 | 数据写入时 | 拒绝写入 / 降级处理 |
| 字段约束校验 | 数据消费时 | 告警 / 跳过 / 修复 |
| 数据质量校验 | 定时任务 | 生成质量报告 |
| SLA 监控 | 持续监控 | 触发告警 / 自动降级 |
嗯,这里要注意:消费阶段的校验不能影响主流程的性能。我建议用异步校验 + 采样校验的方式,核心数据全量校验,非核心数据采样校验。
4.6 废弃阶段:体面地退出
数据契约也有生命周期终点。当数据源下线、业务变更或契约被新版本替代时,就需要进入废弃阶段。
废弃阶段的原则:
- 提前通知——至少提前一个迭代周期通知所有消费者
- 灰度废弃——先标记为「即将废弃」,再正式废弃
- 保留历史——废弃的契约保留只读访问,不删除历史数据
- 清理依赖——确认所有消费者都已迁移后,再清理注册信息
血的教训:我曾经直接删除过一个废弃的契约,结果有 3 个下游服务还在用旧版本,第二天线上直接报错。从那以后,我强制要求废弃流程必须走审批 + 通知 + 确认三步,缺一不可。
废弃阶段的典型流程:
- 生产者发起废弃申请
- 注册中心标记契约为「deprecated」
- 通知所有已绑定的消费者
- 等待确认期(通常 7-30 天)
- 确认无消费者依赖后,正式废弃
- 归档契约定义和历史版本
建议:废弃的契约不要物理删除,而是标记为「archived」状态。万一哪天需要回溯数据,还能找到当时的契约定义。我一般会保留至少 6 个月的废弃契约历史。