簡體   English   中英

在spark-shell中使用全局對象時隱式val序列化

[英]implicit val serialization when using global object in spark-shell

我不清楚為什么(不可序列化)隱式val在這里被序列化(拋出異常):

implicit val sc2:SparkContext = sc
val s1 = "asdf"
sc.parallelize(Array(1,2,3)).map(x1 => s1.map(x => 4))

但是當s1的值在閉包的范圍內時:

implicit val sc2:SparkContext = sc
sc.parallelize(Array(1,2,3)).map(x1 => "asdf".map(x => 4))

我的用例顯然更復雜,但我將其歸結為這個問題。

(解決方案是將隱式val定義為@transient)

這取決於這些行所在的范圍

讓我們看一下三個選項-在method中 ,在沒有s1類中 ,以及在s1類中

object TTT {

  val sc = new SparkContext("local", "test")

  def main(args: Array[String]): Unit = {
    new A().foo()  // works
    new B          // works
    new C          // fails
  }

  class A {
    def foo(): Unit = {
      // no problem here: vars in a method can be serialized on their own
      implicit val sc2: SparkContext = sc
      val s1 = "asdf"
      sc.parallelize(Array(1, 2, 3)).map(x1 => s1.map(x => 4)).count()
      println("in A - works!")
    }
  }

  class B {
    // no problem here: B isn't serialized at all because there are no references to its members
    implicit val sc2: SparkContext = sc
    sc.parallelize(Array(1, 2, 3)).map(x1 => "asdf".map(x => 4)).count()
    println("in B - works!")
  }

  class C extends Serializable {
    implicit val sc2: SparkContext = sc
    val s1 = "asdf" // to serialize s1, Spark will try serializing the YYY instance, which will serialize sc2
    sc.parallelize(Array(1, 2, 3)).map(x1 => s1.map(x => 4)).count() // fails
  }

}

底線-是否隱含,只有當s1sc2是類的成員時,該操作才會失敗,這意味着該類必須進行序列化,並使用它們“拖動”它們。

范圍是火花殼REPL。 在這種情況下,僅當sc2(以及在頂級REPL范圍中定義的任何其他隱式val)是隱式的並且與RDD操作中使用的該范圍的另一個val時才被序列化。 這是因為隱式值需要全局可用,因此會自動序列化到所有工作程序節點。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM