数据契约的四大核心要素:生产者、消费者、Schema、SLA

上一章我们聊了数据契约是什么,以及它为什么重要。这一章,咱们把它的骨架拆开来看。

数据契约不是一张纸,也不是一个文档。它是一套可执行的约定。这套约定由四个核心要素组成:生产者、消费者、Schema 和 SLA。

少了任何一个,契约都不完整。我见过不少团队,只定义了 Schema 就号称有了数据契约。结果呢?生产者和消费者之间照样扯皮。为什么?因为没人承诺数据什么时候到,也没人定义数据出问题了找谁。

下面我们一个一个说清楚。

生产者:数据的源头,也是责任的第一承担者

生产者,就是提供数据的系统或团队。在数据契约里,生产者不只是“发数据的人”。它要承诺三件事:

  • 数据质量:我产出的数据,符合约定的 Schema 和业务规则。
  • 数据可用性:我保证在约定的时间窗口内,数据是可获取的。
  • 变更通知:如果我要改 Schema 或下线数据,必须提前通知消费者。

我个人习惯,在契约里把生产者信息写成这样:

{
  "producer": {
    "system": "order_service",
    "team": "交易中台",
    "owner": "张三",
    "contact": "zhangsan@company.com",
    "change_notice_days": 7
  }
}

这里有个坑。我曾经遇到一个团队,把生产者写成了“数据中台”。结果数据出问题,数据中台说“我只是转发,源头是业务系统”,业务系统说“我不知道有契约这回事”。你看,生产者必须精确到具体的系统和负责人,不能模糊。

注意:生产者不能写成一个部门或一个抽象概念。必须写清楚是哪个系统、哪个接口、哪个表的哪个负责人。否则,出了事找不到人,契约就是废纸。

消费者:不是被动接收,而是有义务的参与者

很多人觉得,消费者就是“用数据的人”,没什么好定义的。其实不然。

消费者在契约里也有明确的义务:

  • 按约定使用数据:不能随意扩展字段含义,不能绕过契约直接读源库。
  • 反馈问题:发现数据异常,要在规定时间内通知生产者。
  • 遵守限流规则:不能无限制地拉取数据,把生产者压垮。

你想想看,如果消费者没有义务,那生产者改了 Schema,消费者不跟进,数据链路就断了。或者消费者一天拉一万次接口,生产者扛不住,所有人都受影响。

我建议在契约里明确消费者的使用场景:

{
  "consumer": {
    "system": "bi_report",
    "team": "商业智能",
    "owner": "李四",
    "usage": "每日离线报表,T+1 更新",
    "max_qps": 10
  }
}

嗯,这里要注意。消费者的“usage”字段很重要。它告诉生产者:你的数据被用来干什么。这样生产者才能判断,自己的数据变更会不会影响下游。

Schema:契约的语法,数据流通的通用语言

Schema 是数据契约里最“硬”的部分。它定义了数据的结构、类型、约束和含义。

没有 Schema,数据就是一堆字节流。有了 Schema,生产者和消费者才能达成共识:这个字段是整数还是字符串?这个字段允许为空吗?这个字段的取值范围是什么?

我个人偏爱用 Avro 或 Protobuf 来定义 Schema。它们自带类型系统和兼容性检查。举个例子:

{
  "type": "record",
  "name": "OrderEvent",
  "fields": [
    {"name": "order_id", "type": "string", "doc": "订单唯一标识"},
    {"name": "user_id", "type": "string", "doc": "用户ID"},
    {"name": "amount", "type": "double", "doc": "订单金额,单位元"},
    {"name": "status", "type": "string", "doc": "订单状态,枚举值: created/paid/shipped/done"},
    {"name": "created_at", "type": "long", "doc": "创建时间,Unix毫秒时间戳"}
  ]
}

Schema 里最容易被忽略的是 兼容性规则。比如,生产者能不能加一个字段?加了之后,消费者会不会报错?

核心原则:Schema 变更必须向后兼容。也就是说,老版本的消费者读新版本的数据,不能报错。常用的策略是“只加字段,不改类型,不删字段”。

我曾经见过一个事故。生产者把一个字段从 int 改成了 string,觉得“反正都是数字,string 也能存”。结果消费者的解析器直接崩溃,因为类型不匹配。那一夜,数据链路断了 6 个小时。

SLA:契约的肌肉,承诺数据服务的质量

SLA 是 Service Level Agreement 的缩写。在数据契约里,它定义了数据服务的质量指标。

没有 SLA 的契约,就像没有罚则的合同。谁都不会当真。

SLA 通常包含以下几个维度:

维度 说明 示例
可用性 数据在约定时间窗口内是否可获取 每日 08:00 前数据必须就绪,可用性 ≥ 99.9%
时效性 数据从产生到可被消费的最大延迟 实时数据延迟 ≤ 5 秒;离线数据 T+1 08:00 前
完整性 数据是否完整,有没有丢失记录 每日数据完整率 ≥ 99.99%
准确性 数据值是否符合业务预期 金额字段误差率 ≤ 0.01%
响应时间 接口或查询的响应速度 API 响应时间 P99 ≤ 200ms

定义 SLA 的时候,我建议遵循一个原则:可测量、可验证。不要写“数据要快”,要写“延迟 ≤ 5 秒”。不要写“数据要准”,要写“准确率 ≥ 99.99%”。

小技巧:SLA 的指标最好能自动化监控。比如,用 Prometheus 采集数据延迟,用 Great Expectations 校验数据质量。一旦 SLA 被违反,自动告警。这样契约才不是摆设。

四大要素的关系:一张图说清楚

这四个要素不是孤立的。它们共同构成了数据契约的完整闭环。我画了一张图,帮你理解它们之间的关系:

数据契约四大核心要素关系图 生产者 提供数据 + 承诺质量 消费者 使用数据 + 遵守约定 Schema 数据结构 + 类型约束 SLA 质量指标 + 监控告警 生产者与消费者通过 Schema 达成数据格式共识,SLA 约束双方的服务质量, 同时 SLA 的监控结果反向驱动生产者和消费者持续改进。

你看,生产者定义数据,消费者使用数据。他们通过 Schema 达成格式共识。SLA 则约束了双方的服务质量。同时,SLA 的监控结果会反馈给生产者和消费者,驱动他们持续改进。

这是一个闭环。缺了任何一个,这个环就断了。

小结一下

四大要素,各有各的职责:

  • 生产者:我是谁,我提供什么数据,我承诺什么。
  • 消费者:我是谁,我用什么数据,我遵守什么。
  • Schema:数据长什么样,字段怎么定义,怎么兼容。
  • SLA:数据多快、多准、多稳,达不到怎么办。

下一章,我们会聊怎么把这些要素落地成一份可执行的契约文档。但在此之前,我建议你先拿自己团队的一个数据链路练练手。把生产者、消费者、Schema、SLA 都写出来。你会发现,很多你以为“清楚”的事情,写下来之后才发现是模糊的。

嗯,这就是数据契约的价值——它逼你把模糊变成清晰。