Kafka 的嵌套 Avro 类型是不是有最佳实践?

Posted

技术标签:

【中文标题】Kafka 的嵌套 Avro 类型是不是有最佳实践?【英文标题】:Is there a best practice for nested Avro Types with Kafka?Kafka 的嵌套 Avro 类型是否有最佳实践? 【发布时间】:2021-12-29 07:44:03 【问题描述】:

嘿,*** 社区,

我有一个关于嵌套 Avro 模式的问题,以及在将它们与 Kafka 一起使用时如何将它们存储在模式注册表中的最佳做法是什么。

TL;DR & Question:在 Avro 模式注册表中存储复杂的嵌套类型的最佳实践是什么?

a)所有子类型作为一个单独的主题(如下所示) b)作为单个主题的嵌套超类型,包含所有子类型 c) 完全不同的东西?

一点上下文:我们的模式由一个主要类型组成,该类型具有一些复杂的子类型(其中一些子类型本身具有子类型)。为了保持干净,我们将每个复杂类型都移到了自己的 *.avsc 文件中。这给我们留下了 ~10 个*.avsc 文件。我们产生的所有消息都有主类型,子类型从不单独发送。 对于上传/注册模式,我们使用gradle plugin。为了让它工作,我们需要将每个子类型完全指定为一个单独的主题,然后定义它们之间的引用,就像这样(在build.gradle.kts):

schemaRegistry 
    url.set("https://$schemaRegistryPath")
    register 
        subject("SubSubType1", "$projectDir/src/main/avro/SubSubType1.avsc", "AVRO")
        subject("SubType1", "$projectDir/src/main/avro/SubType1.avsc", "AVRO")
            .addReference("SubSubType1","SubSubType1",-1)
        subject("MyMainType", "$projectDir/src/main/avro/MyMainType.avsc", "AVRO")
            .addReference("SubType1","SubSubType1",-1)
        // remaining config omitted for brevity
    

这会导致所有子类型在架构注册表中注册为单独的主题:

curl -X GET http://schema-registry:8085/subjects
["MyMainType","Subtype1","Subtype2","Subtype3","SubSubType1","SubSubType2"]%

这感觉很尴尬;我们只生成有效载荷为MyMainType 的 Kafka 消息 - 因此我只需要在注册表中拥有该类型,所有子类型都嵌套在其中,如下所示:

curl -X GET http://schema-registry:8085/subjects
["MyMainType"]%

这个特定的 Gradle 插件似乎无法做到这一点,但看起来 other plugins 处理这个问题的方式相同。所以显然,当在单独的文件中指定 Avro 子类型时,注册它们的唯一方法是将它们注册为单独的主题。

我应该在这里做什么?注册所有子类型,还是将所有*.avsc合并到一个大文件中?

感谢大家的指点!

【问题讨论】:

单独的项目会使用较小的类型吗?如果没有,它们都可以合并成一个更大的。参考文献并不总是存在。我们生存了多年,并构建了大量 CI 工具,而无需注册引用类型 感谢您分享这方面的经验。这是有道理的,但是对于我们目前拥有的子类型的数量,我不愿意将所有这些类型合并到一个文件中,因为这会导致大量重复的类型定义和一个冗长、难以阅读的文件。在进一步阅读/研究后,似乎 Avro 接口定义是要走的路(见下面我的回答)。 【参考方案1】:

不幸的是,似乎没有关于这个主题的大量信息,但这是我发现的关于您使用复杂 Avro 架构的选项:

对于具有少量复杂类型的简单模式,请使用 Avro 模式 (*.avsc) 对于更复杂的架构和嵌套负载,请使用 Avro 接口定义 (*.avdl) - 这些原生支持导入

因此将定义转换为*.avdl 可能是值得的。如果您坚持保留 *.avsc 样式定义,可以使用 Maven 插件来合并这些定义(请参阅 https://michalklempa.com/2020/04/composing-avro-schemas-from-subtypes/)。

但是,我得到的印象是,每当事情变得复杂时,最好使用 Avro IDL。这个blog post 支持这个假设。

【讨论】:

您可以将 AVSC/AVDL 导入其他 AVDL 而不是转换。另外,在过去,我用过这个 - virtualroadside.com/blog/index.php/2014/06/08/…

以上是关于Kafka 的嵌套 Avro 类型是不是有最佳实践?的主要内容,如果未能解决你的问题,请参考以下文章

kafka数据接口定义最佳实践

具有逻辑类型的 Avro 模式不能与最新的 confluent-kafka 一起使用

选择和修改嵌套向量中的条目的最佳实践

如何使用 Avro 二进制编码器对 Kafka 消息进行编码/解码?

最佳实践|从Producer 到 Consumer,如何有效监控 Kafka

kafka-connect-elasticsearch:当使用“write.method”作为 upsert 时,是不是可以在 kafka 主题上使用相同的 AVRO 对象来发送部分文档?