如何在 Avro 中从 GenericRecord 转换为 SpecificRecord 以获得兼容的模式
How to convert from GenericRecord to SpecificRecord in Avro for compatible schemas
Avro SpecificRecord(即生成的 java 类)是否与模式演变兼容? IE。如果我有 Avro 消息源(在我的例子中是 kafka)并且我想将这些消息反序列化为特定的记录,是否可以安全地进行?
我看到的:
- 在模式末尾添加一个字段工作正常 - 可以反序列化为特定记录
- 在中间添加一个字段不会 - 即破坏现有客户
即使消息兼容,这也是一个问题。
如果我能找到新的模式(使用例如 confluent 模式注册表),我可以反序列化为 GenericRecord,但似乎没有办法从 genericrecord 映射到不同模式的 specificrecord..
MySpecificType message = (T SpecificData.get().deepCopy(MySpecificType.SCHEMA$, genericMessage);
在很多地方都提到了 Deepcopy,但它使用索引所以不起作用..
当您拥有两个模式并且它们兼容时,是否有任何安全的方法在两个 avro 对象之间进行映射?即使我可以从 genercrecord 映射到 genericrecord,这也可以做到,然后我可以使用深度复制技巧来完成这项工作。
这里有针对特定数据类型转换的示例测试。都在配置'specificDeserializerProps'
我添加了以下配置并根据需要获取了特定类型。
HashMap<String, String> specificDeserializerProps = new HashMap<String, String>();
specificDeserializerProps.put(KafkaAvroDeserializerConfig.SCHEMA_REGISTRY_URL_CONFIG, "bogus");
specificDeserializerProps.put(KafkaAvroDeserializerConfig.SPECIFIC_AVRO_READER_CONFIG, "true");
specificAvroDeserializer = new KafkaAvroDeserializer(schemaRegistry, specificDeserializerProps);
希望对您有所帮助
默认情况下,KafkaAvroDeserializerConfig.SPECIFIC_AVRO_READER_CONFIG 设置为 false,因此您的 KafkaAvroDeserializer 默认会生成一个 GenericData$Record,而不是您想要的对象(avro 生成 class)。
正如@JARC 所说,您可以通过编程方式启用它。
如果你在Spring引导项目中使用它,这样设置:
spring.kafka.consumer.value-deserializer=io.confluent.kafka.serializers.KafkaAvroDeserializer
spring.kafka.consumer.properties.specific.avro.reader=true
Avro SpecificRecord(即生成的 java 类)是否与模式演变兼容? IE。如果我有 Avro 消息源(在我的例子中是 kafka)并且我想将这些消息反序列化为特定的记录,是否可以安全地进行?
我看到的:
- 在模式末尾添加一个字段工作正常 - 可以反序列化为特定记录
- 在中间添加一个字段不会 - 即破坏现有客户
即使消息兼容,这也是一个问题。
如果我能找到新的模式(使用例如 confluent 模式注册表),我可以反序列化为 GenericRecord,但似乎没有办法从 genericrecord 映射到不同模式的 specificrecord..
MySpecificType message = (T SpecificData.get().deepCopy(MySpecificType.SCHEMA$, genericMessage);
在很多地方都提到了 Deepcopy,但它使用索引所以不起作用..
当您拥有两个模式并且它们兼容时,是否有任何安全的方法在两个 avro 对象之间进行映射?即使我可以从 genercrecord 映射到 genericrecord,这也可以做到,然后我可以使用深度复制技巧来完成这项工作。
这里有针对特定数据类型转换的示例测试。都在配置'specificDeserializerProps'
我添加了以下配置并根据需要获取了特定类型。
HashMap<String, String> specificDeserializerProps = new HashMap<String, String>();
specificDeserializerProps.put(KafkaAvroDeserializerConfig.SCHEMA_REGISTRY_URL_CONFIG, "bogus");
specificDeserializerProps.put(KafkaAvroDeserializerConfig.SPECIFIC_AVRO_READER_CONFIG, "true");
specificAvroDeserializer = new KafkaAvroDeserializer(schemaRegistry, specificDeserializerProps);
希望对您有所帮助
默认情况下,KafkaAvroDeserializerConfig.SPECIFIC_AVRO_READER_CONFIG 设置为 false,因此您的 KafkaAvroDeserializer 默认会生成一个 GenericData$Record,而不是您想要的对象(avro 生成 class)。
正如@JARC 所说,您可以通过编程方式启用它。
如果你在Spring引导项目中使用它,这样设置:
spring.kafka.consumer.value-deserializer=io.confluent.kafka.serializers.KafkaAvroDeserializer
spring.kafka.consumer.properties.specific.avro.reader=true