繁体   English   中英

Spark:mapPartition中的选项抛出Task不可序列化

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM