如何在Spark结构化流中将JSON数据集转换为DataFrame

时间:2018-02-05 07:15:06

标签: apache-spark spark-streaming spark-structured-streaming

我正在使用Spark Structured流来处理来自Kafka的数据。我将每条消息转换为JSON。但是,spark需要显式架构才能从JSON获取列。使用DStreams的Spark Streaming可以执行以下操作

spark.read.json(spark.createDataset(jsons))

其中jsonsRDD[String]。 如果是Spark Structured Streaming类似的方法

df.sparkSession.read.json(jsons)

jsonsDataSet[String]

导致以下异常

Exception in thread "main" org.apache.spark.sql.AnalysisException: Queries with streaming sources must be executed with writeStream.start();;

我认为read会触发执行而不是start,但有没有办法绕过这个?

1 个答案:

答案 0 :(得分:1)

要从Kafka上的JSON流式传输到DataFrame,您需要执行以下操作:

  case class Colour(red: Int, green: Int, blue: Int)

  val colourSchema: StructType = new StructType()
    .add("entity", "int")
    .add("security", "int")
    .add("client", "int")

  val streamingColours: DataFrame = spark
    .readStream
    .format("kafka")
    .load()
    .selectExpr("CAST(value AS STRING)")
    .select(from_json($"value", colourSchema))

  streamingColours
    .writeStream
    .outputMode("complete")
    .format("console")
    .start()

这应创建一个流式DataFrame,并在控制台上显示从Kafka读取的结果。

我不相信有可能使用"推断架构"与流数据集。这是有道理的,因为推断模式会查看大量数据以确定类型是什么等。对于流数据集,可以通过处理第一条消息推断出的模式可能与第二条消息的模式不同,等等Spark需要一个架构来处理DataFrame的所有元素。

我们过去所做的是使用Spark的批处理和使用推断模式处理一批JSON消息。然后导出该模式以用于流式数据集。