Apache Flink从Kafka读取Avro byte []

时间:2016-12-21 04:18:35

标签: java stream apache-kafka apache-flink avro

在回顾示例时,我看到了很多:

FlinkKafkaConsumer08<Event> kafkaConsumer = new FlinkKafkaConsumer08<>("myavrotopic", avroSchema, properties);

我看到他们已经知道架构。

  

在将byte []读入通用记录之前,我不知道架构   然后得到架构。 (因为它可能会从记录变为记录)

有人可以指向我FlinkKafkaConsumer08byte[]读取到地图过滤器中,以便我可以删除一些前导位,然后将byte[]加载到通用记录中吗?

2 个答案:

答案 0 :(得分:1)

如果您使用Confluent的架构注册表,我相信首选的解决方案是使用Confluent提供的Avro serde。这样,我们只需调用deserialize()并使用最新版本的Avro架构的解析在场景后自动完成,无需字节操作。

归结为类似的东西(scala中的示例代码,java解决方案非常相似):

import io.confluent.kafka.serializers.KafkaAvroDeserializer

...

val valueDeserializer = new KafkaAvroDeserializer()
valueDeserializer.configure(
  Map(AbstractKafkaAvroSerDeConfig.SCHEMA_REGISTRY_URL_CONFIG -> schemaRegistryUrl).asJava, 
  false)

...

override def deserialize(messageKey: Array[Byte], message: Array[Byte], 
                       topic: String, partition: Int, offset: Long): KafkaKV = {

    val key = keyDeserializer.deserialize(topic, messageKey).asInstanceOf[GenericRecord]
    val value = valueDeserializer.deserialize(topic, message).asInstanceOf[GenericRecord]

    KafkaKV(key, value)
    }

...

此方法要求消息生成器也与架构注册表集成,并在那里发布架构。这可以使用Confluent&#39; KafkaAvroSerializer

以与上述非常类似的方式完成

我在此处发布了详细说明:How to integrate Flink with Confluent's schema registry

答案 1 :(得分:0)

我正在做类似的事情(我使用09消费者)

在自定义反序列化程序的主代码传递中:

FlinkKafkaConsumer09<Object> kafkaConsumer = new FlinkKafkaConsumer09<>(
                parameterTool.getRequired("topic"), new MyDeserializationSchema<>(),
                parameterTool.getProperties());

自定义反序列化模式读取字节,找出模式和/或从模式注册表中检索它,反序列化为GenericRecord并返回GenericRecord对象。

public class MyDeserializationSchema<T> implements DeserializationSchema<T> {


    private final Class<T> avrotype = (Class<T>) org.apache.avro.generic.GenericRecord.class;

    @Override
    public T deserialize(byte[] arg0) throws IOException {
        //do your stuff here, strip off your bytes
        //deserialize and create your GenericRecord 
        return (T) (myavroevent);
    }

    @Override
    public boolean isEndOfStream(T nextElement) {
        return false;
    }

    @Override
    public TypeInformation<T> getProducedType() {
        return TypeExtractor.getForClass(avrotype);
    }

}