数据契约的构成要素:生产者、消费者、Schema、SLA、语义定义
上一章我们聊了数据契约是什么,说白了就是数据提供方和使用方之间的一份"君子协定"。但光有概念不行,得落地。落地之前,你得先搞清楚一份完整的数据契约到底长什么样,里面都装了些什么。
我个人习惯把数据契约拆成五个核心要素:生产者、消费者、Schema、SLA、语义定义。少了任何一个,契约都不完整。今天咱们就一个一个掰开来看。
核心观点:数据契约不是一张纸,而是一份可执行、可验证的技术约定。五个要素缺一不可,否则就会出现"数据对不上、接口调不通、责任说不清"的尴尬局面。
1. 生产者:谁在提供数据?
生产者,就是数据的源头。它可能是一个微服务、一个数据库、一个 IoT 设备,甚至是一个手工维护的 Excel 文件。嗯,别笑,我在项目里真见过把 Excel 当数据源的生产者。
生产者需要明确告诉消费者:我提供什么数据?数据从哪里来?更新频率是多少? 这些信息必须写进契约里。
- 服务标识:生产者的唯一名称或 ID,比如
order-service、user-profile-api。 - 数据源类型:数据库表、API 接口、消息队列 Topic、文件等。
- 更新机制:实时推送、定时批处理、按需查询。
- 负责人:出了问题找谁?团队名或具体联系人。
我的经验:生产者信息里一定要写清楚"数据源类型"。我曾经接手过一个项目,契约里只写了"订单数据",结果排查了三天才发现数据是从 Kafka Topic 来的,不是从数据库直接查的。这个坑,踩过一次就记住了。
2. 消费者:谁在使用数据?
消费者,就是数据的下游。它可能是另一个微服务、一个数据报表、一个机器学习模型,或者一个外部合作伙伴的系统。
消费者需要声明:我要用哪些数据?用来干什么?对数据质量有什么要求?
- 消费方标识:调用方名称或应用 ID。
- 使用场景:实时交易、离线分析、数据同步等。
- 数据量预期:每天/每小时大概消费多少条记录。
- 依赖等级:核心依赖还是可选依赖?
你想想看,如果消费者不登记自己的使用场景,生产者怎么知道该按什么节奏推送数据?我见过一个案例,消费者拿实时接口的数据去做离线批处理,结果把生产者的数据库拖垮了。这就是没写清楚使用场景的后果。
3. Schema:数据结构长什么样?
Schema 是数据契约里最"硬"的部分。它定义了数据的字段名、类型、长度、是否为空、默认值等。说白了,就是告诉双方:数据长什么样,别传错了。
我个人习惯用 Avro 或 Protobuf 来定义 Schema,因为它们天然支持版本管理和向后兼容。JSON Schema 也行,但做兼容性校验时稍微麻烦一点。
{
"type": "record",
"name": "Order",
"fields": [
{"name": "order_id", "type": "string", "doc": "订单唯一标识"},
{"name": "user_id", "type": "string", "doc": "用户ID"},
{"name": "amount", "type": "double", "doc": "订单金额,单位元"},
{"name": "status", "type": "string", "doc": "订单状态: pending/paid/cancelled"},
{"name": "created_at","type": "long", "doc": "创建时间戳(毫秒)"}
]
}
注意:Schema 里一定要写 doc 字段说明。别偷懒!没有文档的 Schema 就是一堆数字和字符串,别人根本看不懂。我见过一个团队,字段名叫 f1、f2、f3,结果三个月后连写代码的人自己都忘了每个字段代表什么。
4. SLA:服务质量怎么保证?
SLA 是数据契约里的"法律条款"。它约定了生产者必须达到的服务质量指标,以及如果达不到会怎样。
常见的 SLA 指标包括:
| SLA 指标 | 说明 | 典型值 |
|---|---|---|
| 可用性 | 数据接口或数据集的在线率 | 99.9% |
| 延迟 | 数据从产生到可被消费的时间 | 实时 < 5s / 离线 < 1h |
| 吞吐量 | 单位时间内能处理的数据量 | 1000 TPS |
| 数据新鲜度 | 数据与源端的时间差 | 不超过 15 分钟 |
| 数据完整性 | 数据是否完整无缺失 | ≥ 99.99% |
我曾经在一个金融项目里,SLA 里写了"数据延迟不超过 1 分钟",结果生产者的批处理任务跑了 3 分钟。消费者那边直接报警,因为他们的风控模型依赖实时数据。最后两边坐下来重新协商,把 SLA 改成了"不超过 5 分钟",同时消费者调整了自己的缓存策略。你看,SLA 不是单方面定的,是双方谈出来的。
5. 语义定义:数据到底是什么意思?
这是最容易被忽略、但也是最重要的一个要素。Schema 告诉你字段名叫 amount,类型是 double,但 amount 到底代表什么?是含税价还是不含税价?单位是元还是分?
语义定义就是回答这些问题的。它通常包含:
- 业务含义:这个字段在业务场景中代表什么。
- 取值范围:合法值的枚举或范围。
- 单位:金额单位、时间单位、长度单位等。
- 计算逻辑:如果是衍生字段,怎么算出来的?
- 数据来源:原始数据从哪个系统来的?
举个例子:字段 order_amount,Schema 里写的是 double。语义定义里要补充:
- 含义:订单实付金额(含税)
- 单位:人民币元
- 精度:保留两位小数
- 来源:从支付系统回调中获取
- 特殊说明:退款订单该字段为负数
你想想看,如果没有语义定义,消费者拿到 order_amount = 100.50,他敢直接用吗?他得猜:这是含税还是不含税?单位是元还是分?万一猜错了,报表对不上,损失就大了。
五个要素的关系
这五个要素不是孤立的。它们互相依赖,共同构成一份完整的数据契约:
- 生产者 + 消费者:确定数据流转的上下游关系。
- Schema:定义数据的"语法"结构。
- 语义定义:解释数据的"语义"含义。
- SLA:保证数据交付的质量和时效。
少了任何一个,契约都会出现"漏洞"。比如有 Schema 没语义定义,消费者看不懂字段含义;有 SLA 没 Schema,质量指标没法落地检查;有生产者和消费者但没 SLA,出了问题互相甩锅。
我的建议:刚开始做数据契约时,别追求一步到位。先把生产者和消费者定下来,再补 Schema,然后加语义定义,最后再谈 SLA。分步走,更容易落地。我在团队里就是这么推的,效果还不错。