3、Schema版本管理:版本号策略、兼容性管理、Schema Registry介绍
版本管理这事儿,说白了就是给Schema上个“身份证”。
我见过太多团队,一开始觉得Schema简单,随便改改就行。结果上线半年后,生产环境突然报错——老数据写不进新结构,新服务读不了旧字段。那时候再回头补版本管理,成本就高了。
所以,咱们得从一开始就把版本管起来。
3.1 版本号策略:别小看这个数字
版本号不只是个数字,它背后是契约。我个人习惯用语义化版本,格式是 MAJOR.MINOR.PATCH。
| 版本位 | 变更类型 | 举例 |
|---|---|---|
| MAJOR | 不兼容的变更 | 删除字段、修改字段类型 |
| MINOR | 向后兼容的新增 | 添加可选字段、添加默认值 |
| PATCH | 兼容的修复/文档 | 修改描述、调整注释 |
举个例子。你有个用户Schema,v1.0.0 定义了 name 和 age。现在想加个 email 字段,而且老数据没有这个字段也能接受。那这就是 MINOR 变更,版本号升到 v1.1.0。
但如果你要把 age 从 int 改成 string,那对不起,这是 MAJOR 变更。老数据全得跟着改,消费者也得跟着升级。版本号直接跳到 v2.0.0。
3.2 兼容性管理:向前还是向后?
兼容性管理,说白了就是回答一个问题:新Schema能不能跟老数据和平共处?
这里有两个方向,很多人容易搞混:
- 向后兼容(Backward Compatibility):用新Schema写的代码,能读老Schema产生的数据。这是最常见的需求。
- 向前兼容(Forward Compatibility):用老Schema写的代码,能读新Schema产生的数据。这个更难,但有时候必须做。
我建议你记住一个原则:生产环境优先保证向后兼容。为什么?因为数据是持久化的,老数据不会自己升级。你想想看,如果今天改了Schema,昨天存的数据就读不了了,那线上肯定炸锅。
具体到操作层面,常见的兼容性规则有这些:
| 规则 | 说明 | 示例 |
|---|---|---|
| FULL | 同时支持向前和向后 | 只添加可选字段,不删除任何字段 |
| BACKWARD | 新代码能读老数据 | 添加可选字段,或给新字段设默认值 |
| FORWARD | 老代码能读新数据 | 不删除字段,只添加可选字段 |
| NONE | 不保证兼容 | 随意删除或修改字段类型 |
3.3 Schema Registry:版本管理的“中央厨房”
光有版本号和兼容性规则还不够。你得有个地方把这些版本存起来,让所有服务都能查到。这就是 Schema Registry 的活儿。
我最早接触 Schema Registry 是在 Kafka 生态里。那时候团队里有人直接改 Avro Schema,然后重启服务。结果下游消费者全挂了。后来上了 Schema Registry,所有变更都得先注册,通不过兼容性检查就不让上线。嗯,从那以后,这类事故再没发生过。
Schema Registry 的核心功能就三个:
- 存储:保存所有历史版本的 Schema。
- 校验:新注册的 Schema 必须通过兼容性检查。
- 分发:消费者可以按版本号拉取 Schema。
下面这张图,是我自己总结的 Schema Registry 工作流程:
你看,生产者要发数据,先得去 Registry 注册 Schema。Registry 会检查这个新版本跟老版本是否兼容。不兼容?直接拒绝。消费者那边,启动时从 Registry 拉取最新的 Schema,或者指定版本。这样两边用的 Schema 永远是对齐的。
3.4 主流 Schema Registry 选型
市面上常见的 Schema Registry 有这么几个:
| 产品 | 生态 | 特点 |
|---|---|---|
| Confluent Schema Registry | Kafka | 支持 Avro/Protobuf/JSON Schema,兼容性规则最全 |
| Apicurio Registry | 多生态 | 开源,支持 Kafka、ASB、HTTP,REST API 完善 |
| Hortonworks Schema Registry | Hadoop | 主要面向 Hive、HBase 等,现在已并入 Apicurio |
| 自建 Registry | 自定义 | 灵活,但维护成本高,不推荐小团队 |
3.5 实战:版本管理落地要点
最后,分享几个我在项目中踩过的坑和总结的经验:
- 版本号从 1 开始:别从 0 开始。0.x 版本容易让人产生“还没稳定”的错觉,不利于推动规范。
- 兼容性规则要写在 CI 里:手动检查靠不住。我在 CI 流水线里加了一步:提交 Schema 变更时,自动调用 Registry 的兼容性 API。不通过就不让合并。
- 老版本别删:Schema Registry 里的历史版本是审计依据。我曾经因为删了老版本,导致回滚时找不到原始 Schema,折腾了一整晚。
- 文档跟着版本走:每个版本的变更说明要写清楚。别只写“修复bug”,要写“删除了字段xxx,因为yyy”。
版本管理这件事,前期投入不大,但收益是长期的。你想想看,当你的系统有几十个微服务、几百个 Schema 版本时,没有 Registry 和版本策略,那简直就是一场灾难。所以,趁现在规模还小,赶紧把规矩立起来。