如何在Avro中将GenericRecord转换为SpecificRecord以获得兼容的模式

时间:2015-11-26 18:55:09

标签: java avro

Avro SpecificRecord(即生成的java类)是否与模式演变兼容?即如果我有Avro消息来源(在我的情况下,kafka)并且我想将这些消息反序列化为特定记录,是否可以安全地进行?

我所看到的:

  • 在架构的末尾添加一个字段可以正常工作 - 可以将ok反序列化为specificrecord
  • 向中间添加字段不会 - 即打破现有客户

即使消息兼容,这也是一个问题。

如果我能找到新的模式(使用例如汇合模式注册表),我可以反序列化为GenericRecord,但似乎并不是一种从泛型记录映射到不同模式的特定记录的方法。

MySpecificType message = (T SpecificData.get().deepCopy(MySpecificType.SCHEMA$, genericMessage);

在各个地方都提到了Deepcopy,但它使用了索引,因此无法工作..

当你有两个模式并且它们兼容时,是否有任何安全的方法在两个avro对象之间进行映射?即使我可以从genercrecord映射到genericrecord,我也可以这样做,然后我就可以使用deepcopy技巧来完成这项工作。

2 个答案:

答案 0 :(得分:3)

此处有针对特定数据类型转换的示例测试。它全部在配置&specificDeserializerProps'

https://github.com/confluentinc/schema-registry/blob/master/avro-serializer/src/test/java/io/confluent/kafka/serializers/KafkaAvroSerializerTest.java

我添加了以下配置,并根据需要输出了特定的类型。

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);

希望有所帮助

答案 1 :(得分:0)

默认情况下,KafkaAvroDeserializerConfig.SPECIFIC_AVRO_READER_CONFIG 设置为 false,因此您的 KafkaAvroDeserializer 将默认生成一个 GenericData$Record,而不是您想要的对象(avro 生成的类)。

正如@JARC 所说,您可以通过编程方式启用它。

如果是在Spring boot项目中使用,这样设置:

spring.kafka.consumer.value-deserializer=io.confluent.kafka.serializers.KafkaAvroDeserializer
spring.kafka.consumer.properties.specific.avro.reader=true