数据契约基础:什么是数据契约?
聊数据契约之前,我先问个问题:你团队里有没有发生过这种事?
数据生产者拍着胸脯说「这个字段我每天凌晨两点准时产出」,结果消费方早上八点跑任务,发现数据还是空的。两边一扯皮,发现根本没有书面约定——全靠口头承诺。
数据契约,说白了就是给数据生产者和消费者之间签一份「书面合同」。它把双方的权利义务写清楚:你产什么、什么时候产、质量多高、出了问题谁负责。我做了这么多年数据治理,发现很多成本问题,根源都在契约缺失上。
核心要素:Schema、SLA、Owner、血缘
一个完整的数据契约,至少包含四个要素。少了任何一个,后面都可能出大问题。
| 要素 | 含义 | 我踩过的坑 |
|---|---|---|
| Schema | 数据的结构定义,字段名、类型、约束、默认值 | 字段类型从 int 改成 string,消费方没收到通知,ETL 直接崩了 |
| SLA | 服务等级协议,包括产出时间、延迟容忍度、可用性 | 曾经约定「每天凌晨产出」,结果对方凌晨 3 点才跑完,我们 2 点的调度全挂了 |
| Owner | 数据资产的责任人,出了问题能找到人 | 有一次数据延迟,打了 5 个电话才找到负责人,中间浪费了 2 小时 |
| 血缘 | 数据的上下游依赖关系,谁产了谁、谁消费了谁 | 改了一个上游表,下游 20 个任务全挂,没人知道影响范围 |
Schema:契约的「语法」
Schema 定义了数据长什么样。字段名、数据类型、是否可为空、枚举值范围……这些都得写清楚。
我个人习惯在契约里把 Schema 写成类似这样的形式:
{
"table": "order_detail",
"version": "1.2.0",
"fields": [
{"name": "order_id", "type": "string", "nullable": false, "comment": "订单唯一标识"},
{"name": "user_id", "type": "string", "nullable": false, "comment": "用户ID"},
{"name": "amount", "type": "decimal(10,2)", "nullable": false, "comment": "订单金额"},
{"name": "status", "type": "string", "nullable": true, "enum": ["pending", "paid", "cancelled"], "comment": "订单状态"}
],
"partition": ["dt"],
"update_frequency": "daily"
}
嗯,这里要注意:版本号一定要带上。我见过太多团队改了 Schema 不更新版本,消费方还在用旧结构解析,结果全是乱码。
SLA:契约的「时间线」
SLA 不只是「几点产出」这么简单。它应该包含:
- 产出时间:最晚几点必须可用
- 延迟容忍:允许延迟多久,超时怎么处理
- 数据完整性:行数波动范围、空值率上限
- 可用性:月度/季度可用百分比
举个例子,我参与过的一个实时数仓项目,SLA 是这样约定的:
SLA 条款:
- 每日产出截止时间:T+1 02:00(北京时间)
- 延迟容忍:最多 30 分钟,超时自动告警
- 数据完整性:行数波动不超过前 7 日均值的 ±5%
- 空值率:关键字段(order_id, user_id)空值率 < 0.01%
- 可用性:月度 99.5%,季度 99.9%
为什么要把空值率写进去?我曾经遇到一个情况,上游某天程序 bug,order_id 字段 30% 是空值,下游的报表全算错了。因为没有空值率约束,上游觉得「数据产出了就算完成」,责任全在下游没做校验。
Owner:契约的「责任人」
Owner 不是随便填个名字就完事。它要包含:
- 数据 Owner:对数据质量负责的人
- 技术 Owner:负责数据管道维护的人
- 备份 Owner:前两者不在时的替代联系人
- 联系方式:即时通讯、电话、邮箱,至少两种
我建议每个数据资产至少有两个联系人。有一次凌晨 3 点数据延迟,主 Owner 在飞机上,还好有备份联系人,10 分钟定位了问题。
血缘:契约的「地图」
血缘关系告诉你:这份数据从哪来,被谁用过。没有血缘,改一个字段就像拆盲盒——你永远不知道会炸到谁。
血缘信息在契约里可以这样表达:
血缘关系:
- 上游依赖:ods_order_raw(表), user_profile(表)
- 下游消费:dws_order_daily(表), report_dashboard(看板)
- 依赖类型:强依赖(ods_order_raw 不可用则本表不可用)
- 消费方式:实时订阅(dws_order_daily),离线 T+1(report_dashboard)
核心观点:血缘不是事后追溯的工具,而是事前变更的「影响范围说明书」。每次 Schema 变更前,先看血缘,再动手。
契约 vs 传统数据治理
传统数据治理什么样?我经历过。一堆文档、一堆流程、一堆审批。但实际执行起来,文档没人看,流程走形式,审批靠刷脸。
数据契约和传统治理的区别,我用一个表格说清楚:
| 维度 | 传统数据治理 | 数据契约 |
|---|---|---|
| 约定方式 | 文档、邮件、口头 | 结构化、版本化、可编程 |
| 执行保障 | 靠人自觉、事后追责 | 自动化校验、事前阻断 |
| 变更流程 | 审批流、邮件通知 | 契约版本升级、兼容性检查 |
| 问题定位 | 人工排查、扯皮 | 契约违约告警、自动定位 |
| 成本视角 | 关注治理成本 | 关注数据质量引发的浪费 |
说白了,传统治理是「出了事再处理」,数据契约是「事先说好,自动执行」。我见过一个团队,用了契约之后,数据质量问题从平均每周 5 起降到了每月不到 1 起。为什么?因为契约把「模糊的承诺」变成了「可验证的规则」。
一个小建议:刚开始推行数据契约时,别贪多。选 3-5 个核心数据资产试点,把 Schema 和 SLA 先定下来。跑通一个流程,比设计一套完美方案有用得多。
数据契约的核心逻辑
下面这张图,是我自己总结的数据契约运作逻辑。它不是一个静态文档,而是一个持续运行的闭环。
这个闭环怎么理解?
- 定义阶段:生产者和消费者一起敲定 Schema、SLA、Owner、血缘,形成契约文件
- 执行阶段:系统自动校验数据是否满足契约,不满足就告警
- 优化阶段:根据违约记录,调整契约条款,让它更贴近实际
你想想看,传统治理里,这三个阶段是割裂的。文档归文档,执行归执行,优化基本靠「出了大事才想起来」。数据契约把它们串成了一个闭环。
避坑提醒:我曾经在一个项目里,把契约定义得过于严格——字段空值率要求 0%,产出时间精确到分钟。结果呢?每天告警几十条,全是误报。团队疲于处理告警,最后把契约功能关了。契约要「够用就好」,别追求完美主义。
小结
数据契约不是什么高深的概念。它就是一份「数据供需双方的书面约定」。四个要素——Schema、SLA、Owner、血缘——缺一不可。和传统治理相比,它的核心优势是:把模糊的承诺变成可验证的规则,把事后追责变成事前预防。