我正在尝试将Apache Flink应用程序(scala)移植到Spark结构化流。该应用程序的基本工作是:
在处理期间,我要输出日志消息(常规处理信息,解析错误等)。但是-来自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
和类似的类作为子类,您可以在其中放置所有不可序列化的内容,这些将根据操作符/并行性实例化。
答案 0 :(得分:0)
如果要在Spark的map运算符中引入不可序列化的对象(如数据库连接),则可以随时利用mapPartition函数。
mapPartition(iter => {
val log = LoggerFactory.getLogger
iter.map(row => {
....
})
})