3. 数据契约核心要素:Schema定义、数据质量约束、数据血缘与SLA
数据契约不是一张空头支票。它得写清楚几件事:数据长什么样、数据干不干净、数据从哪来到哪去、出了问题谁负责。这四块,就是契约的四大核心要素。
我见过不少团队,上来就搞契约,结果只写了个字段名和类型。上线第一天,下游就炸了——字段为空没人管,数据延迟没人赔。说白了,契约要是只定义结构,那跟一张Excel表没区别。
下面我们一个一个拆开讲。
3.1 Schema定义:契约的骨架
Schema定义是契约最基础的部分。它规定了数据的结构、类型、格式。没有Schema,下游根本不知道该怎么消费数据。
我个人习惯,在契约里至少写清楚以下几项:
- 字段名:大小写敏感,统一风格(比如snake_case)
- 数据类型:INT、STRING、TIMESTAMP等,要精确到长度和精度
- 字段描述:每个字段是干什么的,别让下游猜
- 默认值:字段为空时用什么兜底
- 版本号:Schema版本,兼容性策略(向前/向后)
举个例子,一个用户订单表的契约Schema定义:
{
"schema_version": "1.2.0",
"compatibility": "BACKWARD",
"fields": [
{
"name": "order_id",
"type": "STRING",
"length": 32,
"description": "订单唯一标识,UUID格式",
"nullable": false,
"default": null
},
{
"name": "user_id",
"type": "INT64",
"description": "用户ID,关联用户表主键",
"nullable": false,
"default": null
},
{
"name": "order_amount",
"type": "DECIMAL(10,2)",
"description": "订单金额,单位元",
"nullable": true,
"default": 0.00
},
{
"name": "created_at",
"type": "TIMESTAMP",
"description": "订单创建时间,UTC时区",
"nullable": false,
"default": "CURRENT_TIMESTAMP"
}
]
}
3.2 数据质量约束:契约的肌肉
光有Schema还不够。数据进了湖仓,质量不过关,下游照样没法用。数据质量约束,就是契约里对数据“干净程度”的硬性要求。
常见的约束有三类:
| 约束类型 | 说明 | 示例 |
|---|---|---|
| 非空约束 | 关键字段不能为NULL | user_id NOT NULL |
| 唯一约束 | 字段值在数据集内唯一 | order_id UNIQUE |
| 取值范围约束 | 字段值必须在指定范围内 | order_amount >= 0 AND order_amount <= 999999.99 |
你想想看,如果订单金额出现了负数,下游财务系统直接算错账,谁来赔?所以这些约束必须在数据写入湖仓之前就校验。
我曾经在一个项目中,上游把用户年龄字段传成了负数。下游做用户画像分析,结果平均年龄变成了-5岁。排查了半天,才发现是上游代码bug。从那以后,我坚持在契约里加上取值范围约束,并且用自动化工具在写入时做校验。
质量约束的落地方式:
- 在数据写入API层做校验(实时)
- 在湖仓的ETL管道里做校验(准实时)
- 在数据湖的元数据层做定期扫描(离线)
三种方式组合使用,才能覆盖所有场景。
3.3 数据血缘:契约的脉络
数据血缘,就是数据的“族谱”。它记录了数据从哪来、经过哪些转换、最终去了哪。没有血缘,出了问题你根本不知道影响面有多大。
在数据契约里,血缘信息至少要包含:
- 上游来源:数据来自哪个表、哪个字段、哪个系统
- 转换逻辑:经过了哪些ETL步骤、SQL逻辑、函数处理
- 下游消费方:哪些报表、模型、应用依赖这份数据
- 依赖关系:数据链路中的上下游依赖,包括调度依赖
下面这张图,展示了一个典型的数据血缘链路:
3.4 SLA:契约的底线
SLA(Service Level Agreement)是契约里最“硬”的部分。它规定了数据提供方必须达到的服务水平,以及违约后的处理方式。
常见的SLA指标包括:
- 数据时效性:数据多久更新一次?T+1?实时?
- 数据可用性:数据表/接口的可用时间百分比(99.9%?99.99%?)
- 数据完整性:数据量是否达标?行数偏差在多少以内?
- 数据准确性:关键字段的准确率要求(比如金额字段误差不超过0.01%)
- 响应时间:查询接口的P99延迟是多少?
举个例子,一个实时订单流的SLA定义:
| SLA指标 | 目标值 | 测量方式 | 违约处理 |
|---|---|---|---|
| 数据时效性 | 延迟 < 5分钟 | Kafka消费延迟监控 | 超时30分钟,赔偿下游1小时数据重跑资源 |
| 数据可用性 | 99.9% | Prometheus探活 | 月度可用性低于99.9%,减免下月服务费 |
| 数据完整性 | 行数偏差 < 0.1% | 每日对账任务 | 偏差超0.1%,触发告警并补推数据 |
| 数据准确性 | 金额字段准确率 100% | 抽样校验 + 规则引擎 | 发现一笔错误,立即回滚并修复 |
说实话,SLA这块最容易扯皮。我见过一个项目,上游说“数据延迟不超过1小时”,下游理解成“数据最晚1小时到”。结果有一次数据延迟了59分钟,下游说没超,上游说快超了。后来我们在契约里明确写了“延迟从数据产生时间算起,到湖仓可查询为止”,才把标准统一了。
3.5 四要素的关系
这四个要素不是孤立的。它们共同构成了数据契约的完整体系:
- Schema定义是基础,没有它,其他都无从谈起
- 数据质量约束是保障,确保数据可用
- 数据血缘是追溯能力,出了问题能快速定位
- SLA是承诺,让上下游有据可依
我习惯把它们比作一栋房子:Schema是地基,质量约束是墙体,血缘是水电管线,SLA是物业合同。缺了任何一个,这房子都住不踏实。