数据契约核心要素:Schema定义、SLA承诺、数据血缘、质量指标
上一章我们聊了数据契约是什么,以及它为什么能解决实时数据质量的老大难问题。这一章,咱们来拆解它的四个核心要素。
说白了,一份数据契约就是一份「数据服务合同」。合同里得写清楚:你提供什么数据?数据长什么样?质量怎么保证?出了问题谁负责?这四个要素缺一不可。
核心观点:数据契约不是文档,是可执行的约定。Schema定义、SLA承诺、数据血缘、质量指标,这四者共同构成了数据契约的「四梁八柱」。
2.1 Schema定义:数据的「身份证」
Schema定义是数据契约最基础的部分。它规定了数据的结构、类型、约束和含义。没有清晰的Schema,数据就是一团乱麻。
我个人习惯把Schema定义分为三个层次:
- 结构层:字段名、数据类型、是否可为空、主键、外键等。这是最基础的,也是必须的。
- 语义层:字段的业务含义、枚举值的取值范围、度量单位等。比如「status」字段,值是0、1、2,分别代表什么状态?
- 约束层:数据完整性规则、唯一性约束、引用完整性等。比如「订单金额必须大于0」。
我在项目中遇到过一个问题:两个团队对「用户活跃」的定义不一致。一个团队认为「登录即活跃」,另一个团队认为「有操作行为才算活跃」。结果数据对不上,排查了三天。后来我们在数据契约里明确写了「活跃用户 = 当日有任意操作行为的用户」,问题才解决。
我的建议:Schema定义一定要包含语义层。光有字段名和类型是不够的,业务含义必须写清楚。否则,数据契约就成了「有约无契」。
下面是一个典型的Schema定义示例(使用Avro格式):
{
"type": "record",
"name": "OrderEvent",
"namespace": "com.example.order",
"fields": [
{"name": "order_id", "type": "string", "doc": "订单唯一标识"},
{"name": "user_id", "type": "string", "doc": "用户ID"},
{"name": "amount", "type": "double", "doc": "订单金额,单位:元"},
{"name": "status", "type": "int", "doc": "订单状态:0-待支付,1-已支付,2-已取消"},
{"name": "created_at", "type": "long", "doc": "创建时间,Unix毫秒时间戳"}
]
}
2.2 SLA承诺:数据的「服务等级协议」
SLA承诺是数据契约的「硬约束」。它规定了数据提供方必须达到的服务水平,比如数据延迟、可用性、吞吐量等。
你想想看,如果数据生产方说「数据我发了,你收没收到我不管」,那下游怎么用?SLA就是用来解决这个问题的。
常见的SLA指标包括:
| SLA指标 | 说明 | 典型值 |
|---|---|---|
| 数据延迟 | 从数据产生到数据可消费的最大时间差 | P99 < 5秒 |
| 数据可用性 | 数据服务在统计周期内的可用时间占比 | 99.9% |
| 数据吞吐量 | 单位时间内能处理的数据量 | ≥ 10万条/秒 |
| 数据完整性 | 实际接收数据量与预期数据量的比值 | ≥ 99.99% |
注意:SLA承诺不是越高越好。承诺过高,实现成本会急剧上升;承诺过低,又无法满足业务需求。我曾经见过一个团队承诺「P99延迟小于1秒」,结果为了达到这个指标,投入了大量资源做优化,但业务其实只需要5秒就够了。所以,SLA要「恰到好处」。
在数据契约中,SLA承诺通常以「指标 + 阈值 + 统计周期」的形式定义。比如:
{
"sla": {
"latency": {
"metric": "P99延迟",
"threshold": "5秒",
"period": "1小时"
},
"availability": {
"metric": "可用性",
"threshold": "99.9%",
"period": "1天"
}
}
}
2.3 数据血缘:数据的「家族族谱」
数据血缘记录了数据从产生、加工到消费的全链路。它回答了三个问题:
- 数据从哪里来?(上游数据源)
- 数据经过了哪些处理?(ETL、转换、聚合)
- 数据被谁用了?(下游应用、报表、模型)
数据血缘在数据契约中的作用,说白了就是「出了问题能快速定位」。比如,下游报表发现数据异常,通过血缘关系可以迅速找到是哪个上游环节出了问题。
我曾经遇到过一个线上事故:某个实时大屏的数据突然中断了。排查了半小时才发现,是上游一个数据源改了字段名,但下游没有同步更新。如果当时有数据血缘关系图,这个问题5分钟就能定位。
下面是一个数据血缘的SVG示意图,展示了从数据源到数据消费的完整链路:
2.4 质量指标:数据的「体检报告」
质量指标是数据契约的「验收标准」。它定义了数据质量的好坏,以及如何衡量。
常见的质量指标包括:
- 完整性:数据是否有缺失?比如订单表中,订单金额字段不能为空。
- 准确性:数据是否真实反映了业务?比如用户年龄不能超过150岁。
- 一致性:不同数据源之间的数据是否一致?比如订单金额在交易系统和报表系统中应该一致。
- 及时性:数据是否在预期时间内到达?比如实时数据延迟不能超过5秒。
- 唯一性:数据是否有重复?比如订单ID不能重复。
在数据契约中,质量指标通常以「规则」的形式定义。比如:
{
"quality_rules": [
{
"name": "订单金额非空",
"type": "completeness",
"field": "amount",
"expression": "amount IS NOT NULL",
"threshold": 0.99
},
{
"name": "订单金额范围",
"type": "accuracy",
"field": "amount",
"expression": "amount > 0 AND amount < 1000000",
"threshold": 0.999
},
{
"name": "订单ID唯一",
"type": "uniqueness",
"field": "order_id",
"expression": "COUNT(DISTINCT order_id) = COUNT(order_id)",
"threshold": 1.0
}
]
}
我的经验:质量指标不是越多越好。我建议每个数据契约只定义3-5个核心质量指标。指标太多,维护成本高,而且容易「指标打架」。比如,你既要求数据延迟小于1秒,又要求数据完整性达到100%,这在实时场景下几乎不可能同时做到。
2.5 四要素的关系
这四个要素不是孤立的,它们相互关联、相互支撑:
- Schema定义是基础,没有它,其他要素无从谈起。
- SLA承诺是约束,它规定了数据服务的「底线」。
- 数据血缘是纽带,它连接了数据的上下游。
- 质量指标是标尺,它衡量了数据的好坏。
你可以把数据契约想象成一份「房屋租赁合同」:Schema定义是房子的户型图,SLA承诺是租金和租期,数据血缘是房子的水电线路图,质量指标是房子的验收标准。缺了任何一个,合同都不完整。
总结:数据契约的四个核心要素——Schema定义、SLA承诺、数据血缘、质量指标——共同构成了数据质量的「四道防线」。在实际项目中,我建议你从Schema定义开始,逐步完善其他要素。不要试图一步到位,数据契约是「生长」出来的,不是「设计」出来的。