「事件驱动架构」Kafka中的模式注册表和模式演化

article/2025/9/29 6:14:16

d4bd80ee0fad173839865e3852e528b2.png

在这篇文章中,我们将通过Kafka模式注册表来研究Kafka中的模式演化和兼容性类型。通过对兼容性类型的良好理解,我们可以安全地随着时间的推移对模式进行更改,而不会无意中破坏生产者或消费者的利益。

数据集

在我们的“真实世界中的Hadoop开发者”课程中,有一章专门讨论Kafka。在这一章中,我们从Meetup.com直播RSVP数据到Kafka编写我们自己的产品质量,部署就绪,生产者和消费者与Spring Kafka集成。我们将使用来自Meetup.com的RSVP数据流来解释Kafka模式注册表的模式演化和兼容类型。

用例和项目设置

假设Meetup.com决定使用Kafka来分发RSVPs。在这种情况下,producer程序将由Meetup.com管理,如果我想使用Meetup.com生成的RSVPs,我必须连接到Kakfa集群并使用RSVPs。对于我来说,作为一个消费消息的消费者,我首先需要知道的是模式,即RSVP消息的结构。Kafka中消息的典型模式是这样的。

{ "namespace": "com.hirw.kafkaschemaregistry.producer", "type": "record", "name": "Rsvp", "fields": [ { "name": "rsvp_id", "type": "long" }, { "name": "group_name", "type": "string" }, { "name": "event_id", "type": "string" }, { "name": "event_name", "type": "string" }, { "name": "member_id", "type": "int" }, { "name": "member_name", "type": "string" } ]}

该模式列出了消息中的字段以及数据类型。您可以将模式想象为生产者和消费者之间的契约。当producer生成消息时,它将使用此模式来生成消息。因此,在本例中,每个RSVP消息将具有rsvp_id、group_name、event_id、event_name、member_id和member_name。

Producer是一个Spring Kafka项目,使用上述模式向Kafka编写Rsvp消息。因此,所有发送到Kafka主题的消息都将使用上述模式编写,并使用Avro序列化。我们假设producer代码是由meetup.com维护的。Consumer也是Spring Kafka项目,消费写给Kafka的消息。消费者还将使用上面的模式并使用Avro反序列化Rsvp消息。我们维护消费者项目。

问题

Meetup.com采用了这种分发回函的新方式——通过Kafka。生产者和消费者都同意这个模式,一切都很好。认为模式会永远这样是愚蠢的。假设meetup.com觉得提供member_id字段没有价值并删除了它。你认为会发生什么?这会影响到消费者吗?

member_id字段没有默认值,它被认为是必需的列,因此此更改将影响用户。当生产者删除一个必需的字段时,消费者将看到如下错误

导致:org.apache. kafaca .common. Error . serializationexception:反序列化id为63的Avro消息错误

引起的:org.apache.avro。AvroTypeException:发现com.hirw.kafkaschemaregistry.producer.Rsvp,

期待com.hirw.kafkaschemaregistry.producer.Rsvp,缺少必需字段member_id

0ceca7edfca45d1aa3b25582378afed4.png

如果消费者付钱给消费者,他们会很生气,这将是一个代价非常高昂的错误。有办法避免这样的错误吗?幸运的是,有一些方法可以避免Kafka模式注册表和兼容性类型的错误。Kafka模式注册表为我们提供了检查我们对提议的新模式所做更改的方法,并确保我们对模式所做的更改与现有模式兼容。对于我们的模式,哪些更改是允许的,哪些更改是不允许的,这取决于在主题级别定义的兼容性类型。

在Kafka中有几种兼容性类型。现在让我们逐个研究一下。

落后的(BACKWARD)

如果能够使用新模式生成的数据的使用者也能够使用当前模式生成的数据,则认为模式是向后兼容的。

如果没有显式指定兼容性类型,则向后兼容性类型是架构注册表的默认兼容性类型。现在让我们尝试理解当我们从新模式中删除member_id字段时发生了什么。新的模式向后兼容吗?

在新的模式中,我们删除了member_id。假设消费者已经在使用新模式生成的数据—我们需要询问他是否可以使用旧模式生成的数据。答案是肯定的。在新的模式中,member_id不存在,所以如果向消费者提供了member_id数据,也就是在当前模式中,他读取数据没有问题,因为额外的字段是可以的。所以我们可以说新模式是向后兼容的,Kafka模式注册表将允许这个新模式。

但不幸的是,正如我们在演示中看到的那样,这个变化将影响现有的客户。因此,在向后兼容模式中,使用者应该首先进行更改以适应新模式。这意味着,我们需要首先对消费者进行模式更改,然后才能对生产者进行更改。

如果您对使用者有控制权,或者使用者正在驱动对模式的更改,那么这是可以的。在某些情况下,消费者不会乐意为自己做出改变,尤其是如果他们是付费消费者的话。在这种情况下,向后兼容并不是最好的选择。


d94857ec36efc2433df8864d24240568.png

如果消费者受到更改的影响,为什么架构注册表首先允许更改?

兼容性类型并不保证所有的更改对所有人都是透明的。它为我们提供了一个指导原则,帮助我们理解对于给定的兼容性类型,哪些更改是允许的,哪些更改是不允许的。当允许对兼容类型进行更改时,通过对兼容类型的良好理解,我们将能够更好地了解谁将受到影响,从而能够采取适当的措施。

在我们的当前实例中,允许根据向后兼容类型在新模式中删除member_id。因为根据向后兼容性,能够使用带有新模式的out member_id的RSVP的使用者将能够使用带有member_id的旧模式的RSVP。因此,根据向后兼容性允许进行更改,但这并不意味着如果处理不当,更改不会造成破坏。

在向后兼容模式下,最好在更改模式之前先通知使用者。在我们的例子中,meetup.com应该通知消费者member_id将被删除,并让消费者先删除对member_id的引用,然后改变生产者来删除member_id。这是处理这种特定模式更改的最合适的方法。

在向后兼容模式下,我可以在新模式中添加一个没有默认值的字段吗?

这里,我们试图添加一个名为response的新字段,它实际上是用户的RSVP响应,并且没有默认值。在向后兼容类型中,这种模式更改是否可以接受?你觉得呢?

让我们来看看。通过向后兼容模式,能够使用新模式生成的数据的使用者也能够使用当前模式生成的数据。

因此,假设消费者已经在使用没有默认值的response数据,这意味着它是必需的字段。现在,他可以使用没有响应的当前模式生成的数据吗?答案是否定的,因为使用者希望在数据中得到响应,因为它是必需的字段。因此,建议的模式更改不是向后兼容的,而且模式注册表一开始就不允许这种更改。

这个错误非常清楚,说明“正在注册的模式与以前的模式不兼容”

c0c13c2244896cf2744e5daed4f59f24.png

因此,如果模式与设置的兼容性类型不兼容,模式注册表将拒绝更改,这是为了防止意外更改。

如果我们用默认值更改字段响应会怎样?这种更改是否被认为是向后兼容的?

回答这个问题——“已经在使用响应默认值为“无响应”的数据的消费者是否可以使用当前模式生成的没有响应的数据?”

答案是肯定的,因为当缺少响应字段时,使用带有response的新模式生成的数据的消费者将替换默认值,这是使用当前模式生成数据时的情况。

为了总结,向后兼容性允许删除和添加具有默认值的字段到模式中。与使用默认值添加字段不同,删除字段将影响用户,因此最好首先使用向后兼容类型更新用户。

f36e7f410babec58f27f110862f5bf82.png

BACKWARD_TRANSITIVE

向后兼容性类型检查新版本和当前版本,如果需要对所有注册版本进行此检查,则需要使用向后兼容性类型。


25067c14e9db63b1a3c0964960d5772c.png

向前(FORWARD)

好的,到目前为止,我们已经看到了向后和向后传递兼容性类型。

但是,如果我们不希望模式改变影响当前的消费者呢?也就是说,我们希望避免在从模式中删除member_id时发生的情况。当我们删除member_id时,它突然影响了我们的消费者。如果消费者是付费客户,他们会很生气,这会对你的声誉造成打击。那么,我们如何避免这种情况呢?

我们可以使用向前兼容类型,而不是向后使用默认兼容类型。如果使用当前模式生成的数据的消费者也能够使用新模式生成的数据,则认为模式是转发兼容的。

使用此规则,我们将不能删除新模式中没有默认值的列,因为这会影响使用当前模式的消费者。所以添加字段是可以的,删除可选字段也可以。


f5131e03dc035c1c5912876acbef6341.png

如何改变一个主题的兼容性类型?

在指定主题名称的配置上发出PUT请求,并在请求的主体中将兼容性指定为FORWARD。就是这样。让我们发出请求。

9ffa8ee53f2988c2af84823d61438703.png

现在,当我们检查主题上的配置时,我们会看到兼容性类型现在被设置为FORWARD。既然主题的兼容性类型已更改为FORWARD,我们就不允许删除必需的字段,即没有默认值的列。让我们确认。为什么我们不尝试删除event_id字段,这是一个必需字段。

让我们通过发出REST命令来更新主题的模式。要更新模式,我们将发布一个包含新模式主体的POST。在这个模式中,我们删除了字段event_id。

{“schema”:”{\”type\”:\”record\”,\”name\”:\”Rsvp\”,\”namespace\”:\”com.hirw.kafkaschemaregistry.producer\”,\”fields\”:[{\”name\”:\”rsvp_id\”,\”type\”:\”long\”},{\”name\”:\”group_name\”,\”type\”:\”string\”},{\”name\”:\”event_name\”,\”type\”:\”string\”},{\”name\”:\”member_name\”,\”type\”:\”string\”},{\”name\”:\”venue_name\”,\”type\”:\”string\”,\”default\”:\”Not Available\”}]}”}

请参阅将兼容性类型设置为转发更新实际失败。即使更改了代码、更新了模式并推出了RSVPs,也会收到相同的响应。使用前向兼容性类型,可以保证使用当前模式的消费者能够使用新模式。

2bd662b2e33c1f01e2c64a419544a119.png

FORWARD_TRANSITIVE

仅FORWARD检查带有当前模式的新模式,如果您想检查所有注册的模式,需要将兼容性类型更改为,您猜对了——FORWARD_TRANSITIVE。


e827954802ba76e5d785eb7cc9152b5a.png

完整和没有(FULL & NONE)

还有另外3种兼容性类型。如果希望模式向前兼容和向后兼容,那么可以使用FULL。对于完全兼容类型,只允许添加或删除具有默认值的可选字段。使用当前模式完全检查新模式。如果希望根据所有注册的模式检查新模式,可以使用FULL_TRANSITIVE。与其他类型相比,完全和完全传递兼容性类型具有更多的限制性。

最后一种兼容类型是NONE。NONE表示禁用所有兼容类型。这意味着所有更改都是可能的,这是有风险的,通常不会在生产中使用。

本文http://jiagoushi.pro/node/1107
讨论:知识星球【首席架构师圈】或者加微信小号【cea_csa_cto】或者加QQ群【792862318】
公众号

【jiagoushipro】
【超级架构师】
精彩图文详解架构方法论,架构实践,技术原理,技术趋势。
我们在等你,赶快扫描关注吧。
37624ad1f3ade12b044d6a43a5c079e0.png
微信小号

【cea_csa_cto】
50000人社区,讨论:企业架构,云计算,大数据,数据科学,物联网,人工智能,安全,全栈开发,DevOps,数字化.

ca6d59efbbb3f5b8f4686fc8844195ad.png

QQ群

【792862318】深度交流企业架构,业务架构,应用架构,数据架构,技术架构,集成架构,安全架构。以及大数据,云计算,物联网,人工智能等各种新兴技术。
加QQ群,有珍贵的报告和干货资料分享。

fd80ef5a94a0e4a814028d9d310a74dc.png

视频号【超级架构师】
1分钟快速了解架构相关的基本概念,模型,方法,经验。
每天1分钟,架构心中熟。

682c9fe28d4f7f5cee731bd60dbe086a.png

知识星球向大咖提问,近距离接触,或者获得私密资料分享。知识星球【首席架构师圈】
喜马拉雅路上或者车上了解最新黑科技资讯,架构心得。【智能时刻,架构君和你聊黑科技】
知识星球认识更多朋友,职场和技术闲聊。知识星球【职场和技术】
微博【智能时刻】智能时刻
哔哩哔哩【超级架构师】
抖音【cea_csa_cto】超级架构师
快手【cea_csa_cto】超级架构师
小红书【cea_csa_cto】超级架构师首席架构师智库



谢谢大家关注,转发,点赞和点在看。


http://chatgpt.dhexx.cn/article/j6V2pWc2.shtml

相关文章

IObit Uninstaller(电脑软件彻底卸载, 包含注册表) 彻底解决软件卸载不干净的问题

本文是众多使用技巧中其中的一篇, 全部使用技巧点击链接查看, 或直接查看本专栏其他文章, 保证你收获满满 我主页中的思维导图中内容大多从我的笔记中整理而来,相应技巧可在笔记中查找原题, 有兴趣的可以去 我的主页 了解更多计算机学科的精品思维导图整理 本文可以转载&…

Windows注册表及常见子项

Windows注册表五大根键以及常用注册表项 注册表概述:注册表是Windows操作系统、硬件设备以及客户应用程序得以正常运行和保存设置的核心“数据库”,也可以说是一个非常巨大的树状分层结构的数据库系统。注册表记录了用户安装在计算机上的软件和每个程序…

注册表权限修改

这里写自定义目录标题 欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants 创建一个自定义列表如何创建一个…

webx框架解析

2019独角兽企业重金招聘Python工程师标准>>> WebX框架是阿里巴巴集团开发的,它建立在SpringEx的基础上,具有超强的扩展能力。 一、Webx的层次结构(从里到外) (1)SpringExt:基于Sprin…

Webx mvc 源码

Webx命名规范 Web请求响应 当Webx Framework接收到一个来自WEB的请求以后,实际上它主要做了两件事: 首先,它会增强request、response、session的功能,并把它们打包成更易使用的RequestContext对象。 其次,它会调用相应子应用的pipeline,用它来做进一步的处理。 假如在…

WebX源码研读

WebX是公司应用最为广泛的web框架,目前已经开源。一直以为webX是基于spring MVC的,但其实并不是,那么不同之处到底在何处,又是为什么这样实现?看过了源码,在这里梳理下思路 我以为,在业务层面上…

WebX框架使用说明

前言 标准MVC开源框架有很多(Struts、SpringMVC、Webx),对于生活在开源世界里面的码农来说SpringMVC、Struts是接触比较多,也是最熟悉的框架。 知己知彼 以配置SpringMVC为例,我们常常关注的点主要有以下几个方面&a…

webx学习总结

webx学习总结 一 Webx的概括 WEBX是阿里巴巴的部框架,“就是把页面与Service之间的一些Servlet等公共的东西抽象出,提供相的服务以提高发效率(《接口之Webx介》—何晓峰 )”,可以看出,webx和统的servlet-ac…

Webx MVC分析

Webx框架&#xff1a;http://openwebx.org/ petstore:webx3/webx-sample/petstore/tags/3.0/petstore 编译之后&#xff1a;mvn jetty:run即可, 访问&#xff1a; http://localhost:8081/ Webx MVC(以webx3为基础) 1、webx3的入口点 <filter> <filter-name>…

Webx MVC

首先在Webx中&#xff0c;使用WebxContextLoaderListener替代Spring的ContextLoaderListener&#xff1a; <listener><listener-class>com.alibaba.citrus.webx.context.WebxContextLoaderListener</listener-class></listener><filter><filt…

Webx学习

六月中就要去阿里巴巴实习了,部门使用的web框架是Webx,喜大普奔的发现Webx是开源的,所以认真学习一下。主要参考指导手册 Webx总体介绍 设计理念 这里有许多框架设计的真知灼见! 一个框架的好坏,往往并不是由他所实现的具体功能好坏所决定的,而是由其所使用的基础框架…

webx mysql_idea使用Maven启动maven项目、 webx框架项目

一、打开 二、点击号选择maven 三、 (1)、Working directory : 选择项目路径 (2)、Command line: clean jetty:run-war -Djetty.port8086 -Dautoconfig.charsetUTF-8 -Dmaven.test.skip (3)、VM Options: -server -XX:PermSize256M -XX:MaxPermSize512M (4)、点击Environment V…

webx mysql_Webx项目的获取与验证

在JavaWeb环境配置后就可进行Webx实例项目的获取与研读了。 1.创建一个初始的Demo工程。 1)下载 Webx Maven 项目的目录结构Artifact插件。 2) 创建WebxDemo项目 打开命令行工具(Windows cmd或Unix/Linux bash)&#xff0c;输入如下命令&#xff1a; mvn archetype:generate -D…

Webx框架

Webx是一个框架&#xff0c;它可用来做下面的事情&#xff1a; 创建一个全功能的Web应用 Webx提供了创建一个Web应用所需要的所有必要功能. 创建一个新的Web框架 Webx允许你定制、甚至重写大部分的Webx框架逻辑&#xff0c;从而实现全新的功能&#xff0c;或者和其它应用框…

Webx简介(转)

经常会到博客来看看大家的一些文章&#xff0c;都写的相当精彩&#xff0c;有水平&#xff0c;感觉大家好像都写了&#xff0c;自己没什么写的&#xff0c;后来跟师傅婉佩沟通&#xff0c;才了解到这样想是错的&#xff0c;每个人针对每个东西可能想法观点都不同&#xff0c;写…

WebX入门指南

[说明] 本文围绕WebX的Web框架展开&#xff0c;试图将整个开发中使用的软件栈或者说生态系统串联起来。本文中不讲解原理性的东西&#xff0c;只是讲解各种场景下如何使用WebX相关的技术。入门指南中涉及到的实践指南和原理指南&#xff0c;不会展开&#xff0c;在后续博文中&a…

WebX框架解析及使用教程

WebX框架是阿里巴巴集团开发的&#xff0c;它建立在SpringEx的基础上&#xff0c;具有超强的扩展能力。 一、Webx的层次结构&#xff08;从里到外&#xff09; &#xff08;1&#xff09;SpringExt&#xff1a;基于Spring&#xff0c;提供扩展组件的能力 &#xff08;2&#xf…

VSCode中Emmet使用

文章目录 HTML部分1. 添加类&#xff0c;id&#xff0c;文本和属性2. 嵌套和分组3. 隐式标签4. 定义多个元素* 和 编号$5. 添加虚拟文字6. 其它 CSS部分1. 属性和属性值的缩写2. 属性值的单位其它 HTML部分 1. 添加类&#xff0c;id&#xff0c;文本和属性 div.box#box > …

linux vim emmet,emmet-vim

最近啊&#xff0c;我投奔了网页的开发&#xff0c;看了一本《head first HTML and CSS》的书&#xff0c;感觉非常不错&#xff0c;然后又配置了一些vim里面用到的插件&#xff0c;现在我把学习到的东西记录下来&#xff01; 首先&#xff0c;我不会在这里写emmet 的具体操作方…

Emmet 语法

Emmet语法前身是Zen coding&#xff0c;来提高html和css的编写速度&#xff0c;vscode内部已经集成该语法了 1、快速生成html结构语法 生成标签&#xff1a; 直接输入标签名&#xff0c;再按TAB键&#xff0c;such as 你打个 div 再按tab&#xff0c;就会直接生成 (这里打不出…