模式注册 – 不可怕的模式演进

首先

Confluent Schema Registry是一种集中管理事件类型(Schema)的机制。通常,事件会与其模式一起发送到Apache Kafka,但是使用Schema Registry可以:

    1. 由于可以通过ID指定,可以将Schema中包含的消息的大小大大缩小。

 

    1. 可以对Schema进行版本控制。

 

    可以控制阻止不兼容的Schema更改。

在这篇文章中,我们将特别介绍如何处理#3中的Schema的变更兼容性和版本更新(Schema Evolution) 的方法。

需要亲自尝试

在Confluent Cloud中包含了Schema Registry作为托管服务,您可以直接尝试使用。如果您想在本地尝试,则推荐您使用Confluent提供的演示场景(Docker Compose)。请参考以下步骤。

模式注册表

schema-registry-and-kafka.png
    1. 生产者/消费者双方都向Schema Registry进行注册(在属性中指定Schema Registry的URL)

 

    1. 生产者的序列化程序将Schema注册到Schema Registry。作为回报,将分配并返回一个ID。

 

    1. 生产者将该ID包含在消息中并发送。

 

    消费者的反序列化程序根据ID从Schema Registry获取Schema并进行反序列化。

Schema和其ID会被生产者/消费者缓存,因此在后续的通信中只使用ID进行传递。此外,除生产者/消费者的属性设置外,其他所有操作都会自动完成,开发者无需关注。

模式演进

DB的表定义和API一样,模式也是随着时间而变化的。在基于事件驱动的异步方法中,虽然没有严格的类型要求在通信时是不必要的灵活性,但是如果在这种方法中生产者进行了消费方无法处理的类型更改,将会对系统/业务造成影响。将这种模式变更明确地管理起来被称为模式演化。

当Producer发送新的Schema版本时,Schema注册表将通过检查是否符合指定的兼容性设置来进行管理。通过拒绝不合格的更改,Schema注册表可以阻止消息的发送,从而预防潜在故障。

互換性模式分为三种,每种模式决定了是先进行Producer的更改部署还是先进行Consumer的更改部署。假设存在针对某个Topic的多个Producer和Consumer。

向后兼容性(默认)- 旧的消费者无法处理新的模式 – 先更新消费者
向前兼容性 – 新的消费者无法处理旧的模式 – 先修改生产者
完全兼容性 – 新旧消费者都能处理新旧模式 – 无论哪个先修改都可以

确认是否符合指定的Compatibility是Schema Registry的职责,而根据该Compatibility的顺序进行部署则是开发人员的责任。

从逻辑出发进行反向/前向/全面兼容的考虑

如果不保证Schema的互换性,会引发什么问题,尽管这个互换性有点难理解:

向后兼容性 – 模式中有新的必需字段或已更改现有的必需字段。
向前兼容性 – 模式中应有的必需字段不存在或已更改。
完全兼容性 – 模式的必需字段未经更改。

换句话说,决定兼容性的关键在于如何处理必填字段(而非可选字段)。

另外,必要字段的定义更改将失去任何互换性。生产者/消费者的全面部署(将导致停机),或者在应用程序中进行分支处理(仅为了适应模式演化而需要的代码逻辑),这是一个影响很大的变更。

向后兼容性 – 新增必需字段或更改现有必需字段将导致不兼容。
向前兼容性 – 删除或更改现有必需字段将导致不兼容。
完全兼容性 – 对必需字段进行更改将导致不兼容。

这些兼容性模式是针对当前版本和下一个版本而设计的,每个模式都有通过所有版本指定兼容性的模式(BACKWARD_TRANSITIVE,FORWARD_TRANSITIVE,FULL_TRANSITIVE),但概念是相同的。

最后

约束是确保兼容性的一种方法,使用Schema Registry只是一种途径。并非有某种神奇机制,而是具有非常明确的存在意义,同时还需要理解相应的规范和思维方式。

然而,在许多情况下都需要对这种类型的严格定义,并且特别是在组织内部使用扩展到跨部门时,它将变得必要。当应对与规模相关的挑战时,不仅仅依靠操作来解决,而是系统地处理时,模式演化将成为一种强大的工具。仅仅通过管理事件模式来解决所有问题是不可能的,但首先了解并适应模式演化,将其视为规则建立的基础之一,我希望您能考虑到这一点。

bannerAds