【问题标题】:How to read records in JSON format from Kafka using Structured Streaming?如何使用结构化流从 Kafka 读取 JSON 格式的记录?
【发布时间】:2017-09-04 00:14:30
【问题描述】:

我正在尝试使用structured streaming approach 使用基于 DataFrame/Dataset API 的 Spark-Streaming 从 Kafka 加载数据流。

我用:

  • Spark 2.10
  • 卡夫卡 0.10
  • spark-sql-kafka-0-10

Spark Kafka 数据源已定义底层架构:

|key|value|topic|partition|offset|timestamp|timestampType|

我的数据采用 json 格式,它们存储在 value 列中。我正在寻找一种方法如何从值列中提取基础架构并将接收到的数据帧更新为存储在 value 中的列?我尝试了下面的方法,但它不起作用:

 val columns = Array("column1", "column2") // column names
 val rawKafkaDF = sparkSession.sqlContext.readStream
  .format("kafka")
  .option("kafka.bootstrap.servers","localhost:9092")
  .option("subscribe",topic)
  .load()
  val columnsToSelect = columns.map( x => new Column("value." + x))
  val kafkaDF = rawKafkaDF.select(columnsToSelect:_*)

  // some analytics using stream dataframe kafkaDF

  val query = kafkaDF.writeStream.format("console").start()
  query.awaitTermination()

在这里我得到了异常org.apache.spark.sql.AnalysisException: Can't extract value from value#337;,因为在创建流时,里面的值是未知的......

你有什么建议吗?

【问题讨论】:

    标签: scala apache-spark apache-kafka apache-spark-sql spark-structured-streaming


    【解决方案1】:

    从 Spark 的角度来看,value 只是一个字节序列。它不知道序列化格式或内容。为了能够提取文件,您必须先对其进行解析。

    如果数据被序列化为 JSON 字符串,您有两种选择。您可以 cast valueStringType 并使用 from_json 并提供架构:

    import org.apache.spark.sql.types._
    import org.apache.spark.sql.functions.from_json
    
    val schema: StructType = StructType(Seq(
      StructField("column1", ???),
      StructField("column2", ???)
    ))
    
    rawKafkaDF.select(from_json($"value".cast(StringType), schema))
    

    castStringType,使用get_json_object 按路径提取字段:

    import org.apache.spark.sql.functions.get_json_object
    
    val columns: Seq[String] = ???
    
    val exprs = columns.map(c => get_json_object($"value", s"$$.$c"))
    
    rawKafkaDF.select(exprs: _*)
    

    cast 稍后转换为所需的类型。

    【讨论】:

    • FWIW,我发现这两种替代方案都很笨拙:+ 模式替代方案需要使用 Spark 本机代码的模式规范。因此,如果我们要发送一个复杂的模式,代码必须解析一个模式文件(xsd 等)并构建这个对象。 + get_json_object 替代力量单独弹出路径/字段。我不确定这是什么性能损失。如果 Apache Spark 提供了一种更简单的方法来干净地接受模式文件并生成 Spark/Catalyst 模式对象,我会更喜欢。
    • 另一种获取消息架构的方法(另一种笨拙的方法):stackoverflow.com/questions/48361177/…
    猜你喜欢
    • 2020-03-17
    • 1970-01-01
    • 2017-10-11
    • 2019-08-01
    • 1970-01-01
    • 2018-03-31
    • 1970-01-01
    • 2017-04-04
    相关资源
    最近更新 更多