模式是任何数据平台的重要组成部分。它们是定义数据形状以及属性名称和数据类型的元数据。模式在两个方面很有帮助。首先,它们为数据格式提供了一个固定的蓝图,可以防止在模式上下文中使用格式错误的数据。其次,模式让用户了解如何解析数据以及对数据属性的期望。
Apache Pulsar是一个开源的分布式发布-订阅 (pub-sub) 消息系统,支持服务器到服务器的数据传输
随着时间的推移,随着应用程序的发展,应用程序生成的数据可能也会发生变化。但是,架构更改可能会影响需要特定格式数据的下游数据消费者。如果没有一种方法来管理生产者和消费者之间的模式,就很难在不冒破坏下游应用程序的风险的情况下更改写入消息或事件中的数据。为避免此类问题,消息的架构也必须随着新属性的添加而发展,并允许消费者理解新旧格式的数据。这个概念被称为模式演化,Pulsar 支持它。
在深入探讨 Pulsar 如何实现和支持模式演化之前,本文先讨论模式演化的原因。
模式提供有关原始数据的上下文。它们通常描述系统中的特定实体,包含该实体的所有属性。例如,您可能有一个注册用户的应用程序。它存储用户详细信息,例如姓名、电子邮件地址和年龄。将有一个描述底层数据并提供上下文的用户模式,例如字段名称和其中的数据类型。该架构可能如下所示:
现在,假设您想扩展捕获的数据以包括地址数据并支持直接邮寄给用户。然后,您需要扩展架构以包含用于捕获地址的新字段,例如地址、城市和邮政编码的第一行。包含这些新字段后,架构将如下所示:
这是模式演变的一种简单形式,因为原始字段没有改变,只是添加了新字段。在大多数情况下,这对下游消费者来说不应该是一个重大变化,因为消费者可以继续,就好像新字段不存在一样。消费者只需要更新即可消费和使用新属性。
但是,有时需要修改现有字段以支持新功能。例如,假设用户不愿意给出确切的年龄,而是更改应用程序以捕获 18-24、25-39、40-49 和 60+ 等年龄范围。 age 列需要将其数据类型从整数修改为字符串。
这是一个更复杂的模式演变,因为这可能会破坏正在处理年龄属性并期望它是一个数字或使用严格类型语言(如 Java)解析数字的下游消费者。他们还可以对属性执行数字计算,这将不再适用于其新格式。
为了克服这一挑战,数据平台可以支持模式演化来处理这样的场景。 Pulsar 认识到模式对数据处理的重要性;事实上,它通过包含内置模式演化支持将其视为一等公民。让我们看看 Pulsar 是如何做到这一点的。
Pulsar 在名为“SchemaInfo”的数据结构中定义模式。这是一个特定于 Pulsar 的数据结构,它本身就是一个模式,它描述了通过 Pulsar 传输的消息的模式。每个 `SchemaInfo` 都属于一个主题(消息通道)并描述使用该主题生成和使用的消息。
每个 `SchemaInfo` 都有一个类型,详细说明所使用的模式类型。这可以是整数、字符串或复杂模式(如 Avro 或 Protobuf)中的任何内容。
支持
Pulsar 支持八种不同类型的
回到前面的示例,让我们使用 Pulsar 的兼容性策略来实现模式更改。首先,从初始用户模式(没有地址)开始。
这将是您的架构的 V1。因此,当您第一次实现 Pulsar 生产者或消费者时,将存储此版本的 `SchemaInfo`,并且生产者和消费者将按预期工作。
接下来,您要将新的地址字段添加到您的用户架构中。第一步是咨询架构兼容性策略并确定哪个最适合此更改。使用文档中的“允许更改”列,您正在寻找允许添加新字段的任何策略。这将为您提供 BACKWARD、BACKWARD_TRANSITIVE、FORWARD 和 FORWARD_TRANSITIVE。
当不能保证使用旧版本的消费者可以理解新模式时,应该使用 BACKWARD。当使用最新模式版本的消费者可能无法读取旧版本中的数据时,使用 FORWARD。如果您想首先更新所有消费者以使用新模式,请使用 BACKWARD 策略。否则,FORWARD 是最好的。
从更大的角度来看,Pulsar 将主题模式演化的整个过程称为
模式很少会永远保持不变。随着新功能被引入应用程序,模式通常必须发展以支持这些功能。然而,当模式被修改时,保持数据的生产者和消费者同步通常是一个挑战。
Pulsar 内置的模式演化概念有助于应对这些变化。使用模式兼容性策略,它可以定义模式的不同兼容版本的规则。 Pulsar 将此与模式验证过程结合使用,然后使用这些规则来确定消费者在连接到特定主题时可以使用哪些模式。
也发布在这里。