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

Is there a best practice for nested Avro Types with Kafka?

大家好 Whosebug 社区,

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

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

一点上下文:我们的架构由一个主要类型组成,该主要类型具有一些复杂的子类型(一些子类型本身具有子类型)。为了保持整洁,我们将每个复杂类型移动到其自己的 *.avsc 文件中。这给我们留下了 ~10 *.avsc 个文件。我们产生的所有消息都有主类型,子类型从不单独发送。 对于 uploading/registering 架构,我们使用 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 合并成一个大文件?

谢谢大家指点!

不幸的是,似乎没有关于此主题的大量可用信息,但这是我发现的有关复杂 Avro 模式的选项的信息:​​

  • 对于复杂类型很少的简单模式,请使用 Avro 模式 (*.avsc)
  • 对于更复杂的模式和嵌套负载,请使用 Avro 接口定义 (*.avdl) - 这些本身支持导入

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

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