Apache kafka 是否可以反序列化Avro消息(使用来自Kafka的消息),而不在ConfluentRegistryAvroDeserializationSchema中提供读取器模式

Apache kafka 是否可以反序列化Avro消息(使用来自Kafka的消息),而不在ConfluentRegistryAvroDeserializationSchema中提供读取器模式,apache-kafka,apache-flink,confluent-schema-registry,Apache Kafka,Apache Flink,Confluent Schema Registry,我在ApacheFlink中使用Kafka连接器来访问Confluent Kafka提供的流 除了架构注册表urlConfluentRegistryAvroDeserializationSchema.forGeneric(…)应为“reader”架构。 我不想提供读取模式,而是想使用同一个编写器的模式(在注册表中查找)来读取消息,因为消费者不会有最新的模式 FlinkKafkaConsumer010<GenericRecord> myConsumer = new Fl

我在ApacheFlink中使用Kafka连接器来访问Confluent Kafka提供的流

除了架构注册表url
ConfluentRegistryAvroDeserializationSchema.forGeneric(…)
应为“reader”架构。 我不想提供读取模式,而是想使用同一个编写器的模式(在注册表中查找)来读取消息,因为消费者不会有最新的模式

FlinkKafkaConsumer010<GenericRecord> myConsumer =
        new FlinkKafkaConsumer010<>("topic-name", ConfluentRegistryAvroDeserializationSchema.forGeneric(<reader schema goes here>, "http://host:port"), properties);
myConsumer.setStartFromLatest();
FlinkKafkaConsumer010支农=
新FlinkKafkaConsumer010(“主题名称”,合流注册AvroDeSerializationSchema.forGeneric(,”http://host:port(土地,物业),;
myConsumer.setStartFromLatest();
“使用这些反序列化架构记录将使用从架构注册表检索并转换为静态提供的架构读取”

既然我不想在消费者端保留模式定义,我如何使用writer的模式反序列化来自Kafka的Avro消息


谢谢你的帮助

我认为不可能直接使用
合流注册表avrodeserializationschema.forGeneric
。它旨在与读取器模式一起使用,并且它们具有对此进行检查的前提条件

你必须实现你自己的。两件重要的事情:

  • specific.avro.reader
    设置为false(否则您将获得特定记录)
  • 必须延迟初始化
    KafkaAvroDeserializer
    (因为它本身不可序列化,因为它持有对架构注册表客户端的引用)
import io.confluent.kafka.schemaregistry.client.CachedSchemaRegistryClient;
导入io.confluent.kafka.schemaregistry.client.SchemaRegistrCyclient;
导入io.confluent.kafka.serializers.AbstractKafkaAvroSerDeConfig;
导入io.confluent.kafka.Serializer.KafkaAvroDeserializer;
导入io.confluent.kafka.serializers.KafkaAvroDeserializerConfig;
导入java.util.HashMap;
导入java.util.Map;
导入org.apache.avro.generic.GenericRecord;
导入org.apache.flink.api.common.typeinfo.TypeInformation;
导入org.apache.flink.api.java.typeutils.TypeExtractor;
导入org.apache.flink.streaming.util.serialization.KeyedDeserializationSchema;
公共类KafkaGenericAvroDeserializationSchema
实现KeyedDeserializationSchema{
私有最终字符串注册表URL;
私人临时卡夫卡夫罗德里泽内;
公共KafkaGenericAvroDeserializationSchema(字符串注册表URL){
this.registryUrl=registryUrl;
}
@凌驾
公共GenericRecord反序列化(
字节[]消息键,字节[]消息,字符串主题,整数分区,长偏移量){
checkInitialized();
返回(GenericRecord)内部。反序列化(主题、消息);
}
@凌驾
公共布尔isEndOfStream(GenericRecord nextElement){
返回false;
}
@凌驾
公共类型信息getProducedType(){
返回TypeExtractor.getForClass(GenericRecord.class);
}
私有void checkInitialized(){
if(内部==null){
Map props=newhashmap();
put(AbstractKafkaAvroSerDeConfig.SCHEMA\u REGISTRY\u URL\u CONFIG,registryUrl);
props.put(kafkaavroderializerconfig.SPECIFIC\u AVRO\u READER\u CONFIG,false);
SchemaRegistrCyclient客户端=
新CachedSchemareRegistryClient(
registryUrl,AbstractKafkaAvroSerDeConfig.MAX\u SCHEMAS\u PER\u SUBJECT\u DEFAULT);
内部=新卡夫卡夫罗德里泽(客户、道具);
}
}
}
env.addSource(
新弗林卡夫卡酒店(
话题,,
新的KafkaGenericAvroDeserializationSchema(schemaReigstryUrl),
卡夫卡财产);

默认行为是使用writer模式解析传入消息,然后转换为reader模式。这不是您想要的吗?我不希望它转换,只需要使用writer模式来反序列化消息。我认为您希望将
kafkaavroderializer
包装/改编为
KeyedDeserializationSchema
,并确保将
specific.avro.reader
设置为
false
,这将为您提供原始
genericord
,因为它们是由生产者发出的。
env.addSource(
  new FlinkKafkaConsumer<>(
    topic, 
    new KafkaGenericAvroDeserializationSchema(schemaReigstryUrl), 
    kafkaProperties));