登录Spark结构化流/ SparkException:任务不可序列化

时间:2019-02-26 09:28:45

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

我正在尝试将Apache Flink应用程序(scala)移植到Spark结构化流。该应用程序的基本工作是:

  • 阅读来自kafka的消息
  • 进行一些转换/处理
  • 将零个或多个消息输出到kafka

在处理期间,我要输出日志消息(常规处理信息,解析错误等)。但是-来自Flink-处理将在对我的.map / Dataset[Node]对象进行操作的一个或多个Dataset[MyCaseClass]运算符中完成。不幸的是,在这些运算符中,所有内容都必须可序列化,这对我的记录器来说不是真的(使用scala-logging)。

因此,当尝试使用记录器时,我得到:org.apache.spark.SparkException: Task not serializable

示例:

    spark.readStream.format("kafka")
      .option("kafka.bootstrap.servers", host + ":" + port)
      .option("subscribe", topic)
      .load()
      .selectExpr("CAST(value AS STRING)")
      .as[String]
      .map(n =>
      {
        // processing here

        log.warn("bla")      // <-- no-go

        <root></root>.asInstanceOf[Node]
      })
      .map(_.toString())
      .writeStream
      .format("kafka")
      .option("kafka.bootstrap.servers", host.get + ":" + port.get)
      .option("topic", topic.get)
      .option("checkpointLocation", "myDir")
      .start()
      .awaitTermination()

推荐的记录方式是不可序列化的,推荐的处理方式是什么?在Flink中,可以选择将RichMapFunction和类似的类作为子类,您可以在其中放置所有不可序列化的内容,这些将根据操作符/并行性实例化。

1 个答案:

答案 0 :(得分:0)

如果要在Spark的map运算符中引入不可序列化的对象(如数据库连接),则可以随时利用mapPartition函数。

mapPartition(iter => {
    val log = LoggerFactory.getLogger
    iter.map(row => {
        ....
    })
})