Pulsar 2.5.0 之 Schema 演化与相容性
官网原文标题《Schema evolution and compatibility》
翻译时间:2020-02-15
官网原文地址: pulsar.apache.org/docs/en/sch…
通常,schema在很长一段时间内不会保持不变。相反,它们经过进化以满足新的需求。
本章探讨Pulsar schema是如何演变的,以及Pulsar schema兼容性检查策略是什么。
Schema 进化
Pulsar schema是在名为SchemaInfo的数据结构中定义的。
与主题一起存储的每个SchemaInfo都有一个版本。版本用于管理主题中发生的schema更改。
使用 SchemaInfo生成的消息被标记为schema版本。当Pulsar客户机使用消息时,Pulsar客户机可以使用schema版本检索相应的 SchemaInfo,并使用正确的schema信息反序列化数据。
什么是Schema 进化?
Schema 存储属性和类型的详细信息。为了满足新的业务需求,您需要随着时间的推移不可避免地更新模式,这称为schema 进化。
任何Schema更改都会影响下游使用者。Schema演化确保下游消费者可以无缝地处理用旧模式和新模式编码的数据
Pulsar schema应该如何演变?
答案是Pulsar schema 兼容性检查策略。它确定 schema 在主题中如何比较旧模式和新模式。
有关详细信息,请参阅 Schema compatibility check strategy.
Pulsar如何支持schema演变?
-
当producer/consumer/reader连接到broker时,broker将部署由
schemaRegistryCompatibilityCheckers配置的schema兼容性检查器,以强制进行架构兼容性检查。schema兼容性检查器是每个schema类型一个实例。目前,Avro和JSON都有自己的兼容性检查器,而所有其他schema类型都共享默认的兼容性检查器,schema演化被禁用。 -
producer/consumer/reader将
SchemaInfo发送给broker。 -
broker知道schema类型并定位该类型的schema兼容性检查器。
-
broker使用检查程序通过应用其兼容性检查策略来检查
SchemaInfo是否与主题的最新schema兼容。目前,兼容性检查策略是在命名空间级别配置的,并应用于该命名空间中的所有主题。
Schema兼容性检查策略
Pulsar有8种schema 兼容性检查策略,总结如下表。
假设您有一个包含三个模式(V1、V2和V3)的主题,V1是最早的,V3是最新的:
| 兼容性检查策略 | 定义 | 允许更改 | 检查哪个 schema | 优先级 |
|---|---|---|---|---|
ALWAYS_COMPATIBLE |
禁用兼容性检查策略 | 允许所有更改 | 所有之前版本 | Any order |
ALWAYS_INCOMPATIBLE |
禁用更新schema结构 | 允许所有禁止 | 无 | 无 |
BACKWARD |
使用 schema V3 的消费者可以处理生产者使用 schema V3 或 V2 编写的数据 | 添加可选字段删除字段 | 最新版本 | Consumers |
BACKWARD_TRANSITIVE |
使用 schema V3 的消费者可以处理生产者使用 schema V3、V2 或 V1 编写的数据。 | 添加可选字段删除字段 | 所有之前版本 | Consumers |
FORWARD |
使用 schema V3 或 V2 的消费者可以处理生产者使用 schema V3 编写的数据。 | 添加可选字段删除字段 | 最新版本 | Producers |
FORWARD_TRANSITIVE |
使用 schema V3、V2 或 V1 的消费者可以处理生产者使用 schema V3 编写的数据 | 添加可选字段删除字段 | 所有之前版本 | Producers |
FULL |
架构 V3 和 V2 之间向后和向前兼容 (默认策略) | 修改可选字段 | 最新版本 | Any order |
FULL_TRANSITIVE |
架构 V3、V2 和 V1 之间向后和向前兼容 | 修改可选字段 | 所有之前版本 | Any order |
ALWAYS_COMPATIBLE and ALWAYS_INCOMPATIBLE
| 兼容性检查策略 | 定义 | 注意 |
|---|---|---|
ALWAYS_COMPATIBLE |
禁用schema兼容性检查 | 无 |
ALWAYS_INCOMPATIBLE |
禁用schema演化 | 除了Avro and JSON schema之外,其他所有的兼容性检查默认策略 ALWAYS_INCOMPATIBLE ,而Avro and JSONschema 兼容性默认策略FULL |
示例
示例 1
在某些情况下,应用程序需要在同一Pulsar主题中存储几种不同类型的事件。
特别是,当以 Event Sourcing 样式开发数据模型时,可能会有几种事件影响实体的状态。
例如,对于用户实体,有userCreated, userAddressChanged和userEnquiryReceived事件。应用程序要求始终以相同的顺序读取这些事件。
因此,这些事件需要在同一个Pulsar分区内维持秩序。这个应用程序可以使用ALWAYS_COMPATIBLE来允许在同一主题中共存不同类型的事件。
示例 2
有时我们也会做出不相容的改变。例如,您正在将字段类型从“string”修改为“int”。
在这种情况下,您需要:
-
同时将所有生产者和使用者升级到新的架构版本。
-
(可选)创建一个新主题并开始迁移应用程序以使用新主题和新schema,从而避免在同一主题中处理两个不兼容的版本。
BACKWARD and BACKWARD_TRANSITIVE
假设您有一个schema包含三个版本(V1、V2和V3)的主题,V1是最早的,V3是最新的:
| 兼容性检查策略 | 定义 | 描述 |
|---|---|---|
BACKWARD |
消费者使用新schema处理生产者使用上一个schema写入的数据 | 消费者使用schema V3处理生产端使用的schema V3 or V2写入的数据 |
BACKWARD_TRANSITIVE |
消费者使用新schema处理生产者使用所有之前版本写入的数据 | 消费者使用schema V3处理生产端使用的schema V3 or V2or V1写入的数据 |
示例
示例1
删除字段。
创建的消费者处理事件过程,可以处理使用包含该字段的旧schema ,并且使用者将忽略该字段。
示例2
您希望将所有Pulsar数据加载到Hive数据仓库中,并对数据运行SQL查询。
即使数据已更改,相同的SQL查询需要能继续运行。
为了支持他们,您的schema可以使用BACKWARD策略 。
FORWARD and FORWARD_TRANSITIVE
假设您有一个包含三个模式(V1、V2和V3)的主题,V1是最早的,V3是最新的:
| 兼容性策略 | 定义 | 描述 |
|---|---|---|
FORWARD |
消费者最新schema处理生产端使用最新schema写入的数据,尽管不在最新schema中兼容不是很好。 | 消费者使用schema V3 or V2处理生产端使用的schema V3写入的数据 |
FORWARD_TRANSITIVE |
消费者使用所有之前schema处理生产端使用最新schema写入的数据 | 消费者使用schema V3 or V2or V1处理生产端使用的schema V3写入的数据 |
示例
示例 1
添加字段
在大多数数据格式中,消费者编写的事件可以继续运行,即使他们的事件中收到包含的新字段。
示例 2
如果使用者将应用程序逻辑绑定到schema的完整版本,则当schema发展时,应用程序逻辑可能不会立即更新。在这种情况下,您需要将带有新模式的数据投影到应用程序理解的旧模式上。
因此,您可以使用FORWARD 策略来改进schema,以确保旧模式可以用新模式编码的数据。
FULL and FULL_TRANSITIVE
假设您有一个包含三个模式(V1、V2和V3)的主题,V1是最早的,V3是最新的:
| 兼容性策略 | 定义 | 描述 | 注意 |
|---|---|---|---|
FULL |
模式既向后兼容又向前兼容,这意味着:使用最后一个模式的消费者可以处理生产者使用新模式编写的数据,而使用新模式的消费者可以处理生产者使用最后一个模式编写的数据 | 使用schema V3的消费者可以处理生产者使用schemaV3或V2编写的数据。使用schema V3或V2的消费者可以处理生产者使用架构V3编写的数据 | 除了Avro and JSON schema之外,其他所有的兼容性检查默认策略 ALWAYS_INCOMPATIBLE ,而Avro and JSONschema 兼容性默认策略FULL |
FULL_TRANSITIVE |
新schema与以前注册的所有schema向后和向前兼容 | 使用schemaV3的消费者可以处理生产者使用schema V3、V2或V1编写的数据。使用schema V3、V2或V1的消费者可以处理生产者使用模式V3编写的数据。 | 无 |
示例
在某些数据格式(例如Avro)中,可以使用默认值定义字段。因此,添加或删除中具有默认值的字段是完全兼容的。
Schema 验证
当生产者或消费者尝试连接到主题时,broker执行一些检查以验证schema。
Producer 生产者
当生产者尝试连接到主题(假设忽略schema自动创建)时,broker执行以下检查:
- 检查生产者所携带的模式是否存在于架构注册表中
- 如果架构已经注册,则生产者将连接到broker并使用该schema生成消息
- 如果架构未注册,则Pulsar将根据配置的兼容性检查策略验证是否允许注册schema
Consumer 消费者
当使用者尝试连接到主题时,broker会根据配置的架构兼容性检查策略检查所携带的schema 是否与注册的架构兼容。
| 兼容性检查策略 | 检查逻辑 |
|---|---|
ALWAYS_COMPATIBLE |
All pass |
ALWAYS_INCOMPATIBLE |
No pass |
BACKWARD |
Can read the last schema |
BACKWARD_TRANSITIVE |
Can read all schemas |
FORWARD |
Can read the last schema |
FORWARD_TRANSITIVE |
Can read the last schema |
FULL |
Can read the last schema |
FULL_TRANSITIVE |
Can read all schemas |
客户端升级顺序
客户端应用程序的升级顺序由兼容性检查策略决定。
例如,生产者使用模式向Pulsar写入数据,消费者使用模式从Pulsar读取数据。
| 兼容性检查策略 | 升级顺序 | 描述 |
|---|---|---|
ALWAYS_COMPATIBLE |
任意顺序 | 兼容性检查被禁用。因此,您可以按任意顺序升级生产者和消费者。 |
ALWAYS_INCOMPATIBLE |
无 | 模式进化被禁用 |
BACKWARD BACKWARD_TRANSITIVE |
消费者 | 无法保证使用旧架构的使用者可以读取使用新架构生成的数据。因此,首先升级所有使用者,然后开始生成新数据。 |
FORWARD FORWARD_TRANSITIVE |
生产者 | 无法保证使用新架构的使用者可以读取使用旧架构生成的数据。因此,首先升级所有生产者以使用新架构,并确保已使用旧架构生成的数据对使用者不可用,然后升级使用者。 |
FULL FULL_TRANSITIVE |
任何一端 | 无法保证使用旧架构的使用者可以读取使用新架构生成的数据,而使用新架构的使用者可以读取使用旧架构生成的数据。因此,您可以按任意顺序升级生产者和使用者。 |
关注公众号:TalkNewClass 免费阅读pulsar 专栏文章以及进群讨论交流学习