如何在读取来自Kafka的消息流时处理Avro消息?

时间:2017-12-16 04:39:19

标签: apache-spark spark-structured-streaming

以下代码读取来自Kafka的消息,消息在Avro中,那么如何解析消息并将其放入Spark 2.2.0中的数据框?

Dataset<Row> df = sparkSession.readStream()
            .format("kafka")
            .option("kafka.bootstrap.servers", "localhost:9092")
            .option("subscribe", "topic1")
            .load();

这个https://github.com/databricks/spark-avro库没有流媒体案例。

1 个答案:

答案 0 :(得分:2)

  

如何解析消息并将其放入Spark 2.2.0中的数据框?

这是你的家庭练习,需要一些编码。

  

这个https://github.com/databricks/spark-avro库没有流媒体案例。

我已经被告知(并且在这里看到了几个问题)spark-avro 支持Spark Structured Streaming(又名Spark Streams)。它适用于非流式数据集,但无法处理流式数据集。

这就是为什么我写这是你必须自己编码的原因。

可能如下所示(为简单起见,我使用Scala):

// Step 1. convert messages to be strings
val avroMessages = df.select($"value" cast "string")

// Step 2. Strip the avro layer off
val from_avro = udf { (s: String) => ...processing here... }
val cleanDataset = avroMessages.withColumn("no_avro_anymore", from_avro($"value"))

这需要开发一个from_avro自定义UDF,它可以做你想要的(并且类似于Spark使用from_json标准函数处理JSON格式的方式!)

或者(以稍微更先进的?/复杂的方法)为Kafka中的Avro格式的数据集编写自己的自定义流Source并使用它。

Dataset<Row> df = sparkSession.readStream()
            .format("avro-kafka") // <-- HERE YOUR CUSTOM Source
            .option("kafka.bootstrap.servers", "localhost:9092")
            .option("subscribe", "topic1")
            .load();

我还没找到可行的avro-kafka格式。它确实可行,但同时做两件事,即从Kafka 读取Avro转换,并且不相信在Spark Structured Streaming和软件工程中做事的方式一般来说。我希望有一种方法可以一种接一种地应用一种格式,但是在Spark 2.2.1中这是不可能的(并且也没有计划用于2.3)。

我认为UDF是目前最好的解决方案。

只是想一想,你也可以编写一个自定义的Kafka Deserializer,它会在Spark加载消息时进行反序列化。