Spark将变量值序列化为null而不是其实际值

时间:2020-04-30 15:58:23

标签: scala apache-spark apache-spark-2.2

我对Spark的代码向运行它的节点的分配机制的理解只是粗略的,当我希望为每个分区实例化一个类时,我无法在Spark的mapPartitions API中成功运行我的代码。一个争论。

下面的代码运行良好,直到我将类MyWorkerClass演化为需要一个参数为止:

  val result : DataFrame =
    inputDF.as[Foo].mapPartitions(sparkIterator => {

      // (1) initialize heavy class instance once per partition
      val workerClassInstance = MyWorkerClass(bar)

      // (2) provide an iterator using a function from that class instance
      new CloseableIteratorForSparkMapPartitions[Post, Post](sparkIterator, workerClassInstance.recordProcessFunc)
    }

在我有(或选择)向类MyWorkerClass添加构造函数参数的时间点上,上面的代码运行良好。传递的参数值在工作程序中显示为null,而不是bar的实际值。该参数的序列化以某种方式无法按预期工作。

您将如何处理?


其他想法/评论

我将避免添加庞大的代码CloseableIteratorForSparkMapPartitions -它仅提供Spark友好的迭代器,甚至可能不是最优雅的实现。

据我了解,构造函数参数没有正确地传递给Spark工作者,这是因为在序列化要在Spark工作者上执行的东西时,Spark如何捕获状态。但是,实例化该类确实可以无缝地使该类中包含的繁重资产–通常可用于上述代码最后一行中提供的功能;该类似乎确实对每个分区实例化。实际上,这是使用mapPartitions而不是map的有效的关键用例。

参数传递给它的实例化使我难以确定如何启用或解决。在我的情况下,该参数是仅在程序开始运行后才知道的值(即使在我的作业的整个执行过程中始终不变;它实际上是程序参数)。我确实需要将其传递给类的初始化。

我试图通过提供一个函数来解决问题,该函数使用其输入参数实例化MyWorkerClass,而不是像上面那样直接实例化,但这并没有解决问题。

问题的根本症状也不例外,只是在实例化barMyWorkerClass的值将仅为null,而不是{{ 1}},这在我包围上面包含的代码段的代码范围中是众所周知的!

*一个相关的old Spark issue discussion here

0 个答案:

没有答案