以下代码读取来自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库没有流媒体案例。
答案 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加载消息时进行反序列化。