[英]Spark: Option in mapPartition throwing Task not serializable
以下是Task not serializable
的火花。
val mergedDF: Dataset[String] = readyToMergeDF
.mapPartitions((rows: Iterator[Row]) =>
mergePayloads(rows, Some(schemaForDataValidation.value))
)
但是如果不通过该选项,它就可以正常工作:
val mergedDF: Dataset[String] = readyToMergeDF
.mapPartitions((rows: Iterator[Row]) =>
mergePayloads(rows)
)
其中schemaForDataValidation
是广播的 Map (尝试不广播 - 产生相同的错误):
lazy val schemaForDataValidation: Broadcast[Map[String, Map[String, Any]]] = getSchemaForValidation
并且mergePayloads
将以下签名放在另一个 Object (扩展Serializable
)中:
object UpdateTableMethods extends Logging with Serializable {
def mergePayloads(iterator: Iterator[Row], schemaOpt: Option[Map[String, Map[String, Any]]] = None): Iterator[String]
我检查了Option
class 源代码。 Some
情况是 class - 因此是可序列化的,并且Option
本身扩展了Serializable
。 实际上,我也尝试过不将参数作为选项传递,而是传递一个可以为空/null 的 Map。
感谢你的帮助。
谢谢你们。
此问题的解决方案:使用使用它的方法将变量注入可序列化的 class 中。
val merger = PayloadsMerger(schemaForDataValidationBroadcast.value)
val mergedDF: Dataset[String] = readyToMergeDF
.mapPartitions((rows: Iterator[Row]) =>
merger.merge(rows)
)
其中PayloadsMerger
携带变量和方法:
case class PayloadsMerger(expectedSchema: Option[Map[String, Map[String, Any]]]) {
def merge(iterator: Iterator[Row]): Iterator[String] = {
PayloadsMerger.mergePayloads(iterator, expectedSchema)
}
}
使用这种clousure技术可以实现序列化,因为 scala case classes mixin serializable
trait 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.