簡體   English   中英

Spark Scala:任務不可序列化錯誤

[英]Spark Scala: Task Not serializable error

我正在使用帶有 Scala 插件和火花庫的 IntelliJ 社區版。 我仍在學習 Spark 並且正在使用 Scala Worksheet。

我編寫了以下代碼來刪除字符串中的標點符號:

def removePunctuation(text: String): String = {
  val punctPattern = "[^a-zA-Z0-9\\s]".r
  punctPattern.replaceAllIn(text, "").toLowerCase
}

然后我閱讀了一個文本文件並嘗試刪除標點符號:

val myfile = sc.textFile("/home/ubuntu/data.txt",4).map(removePunctuation)

這給出了如下錯誤,任何幫助將不勝感激:

org.apache.spark.SparkException:在 org.apache.spark.util.ClosureCleaner$.ensureSerializable(/home/ubuntu/src/main/scala/Test.sc:294) 處的任務不可序列化在 org.apache.spark.util .ClosureCleaner$.org$apache$spark$util$ClosureCleaner$$clean(/home/ubuntu/src/main/scala/Test.sc:284) 在 org.apache.spark.util.ClosureCleaner$.clean(/home /ubuntu/src/main/scala/Test.sc:104) 在 org.apache.spark.SparkContext.clean(/home/ubuntu/src/main/scala/Test.sc:2090) 在 org.apache.spark。 rdd.RDD$$anonfun$map$1.apply(/home/ubuntu/src/main/scala/Test.sc:366) 在 org.apache.spark.rdd.RDD$$anonfun$map$1.apply(/home /ubuntu/src/main/scala/Test.sc:365) 在 org.apache.spark.rdd.RDDOOperationScope$.withScope(/home/ubuntu/src/main/scala/Test.sc:147) 在#worksheet# .#worksheet#(/home/ubuntu/src/main/scala/Test.sc:108) 引起:java.io.NotSerializableException:A$A21$A$A21 序列化堆棧:-對象不可序列化(類:A$ A21$A$A21,值:A$A21$A$A21@62db3891) - 字段(類:A$A21$A$A21$$anonfun$words$1,名稱:$ 外部,類型:類 A$A21$A$A21) - org.apache.spark.serializer.SerializationDebugger$.improveException(SerializationDebugger.scala: 40) 在 org.apache.spark.serializer.JavaSerializationStream.writeObject(JavaSerializer.scala:46) 在 org.apache.spark.serializer.JavaSerializerInstance.serialize(JavaSerializer.scala:100) 在 org.apache.spark.util.ClosureCleaner $.ensureSerializable(ClosureCleaner.scala:295) 在 org.apache.spark.util.ClosureCleaner$.org$apache$spark$util$ClosureCleaner$$clean(ClosureCleaner.scala:288) 在 org.apache.spark.util。 ClosureCleaner$.clean(ClosureCleaner.scala:108) at org.apache.spark.SparkContext.clean(SparkContext.scala:2094) at org.apache.spark.rdd.RDD$$anonfun$map$1.apply(RDD.scala) :370) 在 org.apache.spark.rdd.RDD$$anonfun$map$1.apply(RDD.scala:369) 在 org.apache.spark.rdd.RDDOperationScope$.withScope(RDDOperationScope.scala:151) 在 org .apache.spark.rdd.RDDOperationScope$.withScope(RDDOperationScope.scala:112) 在 org.ap ache.spark.rdd.RDD.withScope(RDD.scala:362) at org.apache.spark.rdd.RDD.map(RDD.scala:369) at A$A21$A$A21.words$lzycompute(Test. sc:27) 在 A$A21$A$A21.words(Test.sc:27) 在 A$A21$A$A21.get$$instance$$words(Test.sc:27) 在 A$A21$。 main(Test.sc:73) at A$A21.main(Test.sc) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect .DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.jetbrains.plugins.scala.worksheet.MyWorksheetRunner.main(MyWorksheetRunner.java:22)

正如 T. Gaweda 已經指出的那樣,您很可能在一個不可序列化的類中定義您的函數。 因為它是一個純函數,即它不依賴於封閉類的任何上下文,我建議您將它放入一個應該擴展Serializable的伴隨對象中。 這將是 Scala 的 Java 靜態方法的等價物:

object Helper extends Serializable {
  def removePunctuation(text: String): String = {
    val punctPattern = "[^a-zA-Z0-9\\s]".r
    punctPattern.replaceAllIn(text, "").toLowerCase
  }
}

正如@TGaweda 所建議的那樣,Spark 的SerializationDebugger非常有助於識別“從給定對象到有問題對象的序列化路徑”。 堆棧跟蹤中“序列化堆棧”之前的所有美元符號表示您的方法的容器對象是問題所在。

雖然在你的容器類上使用Serializable是最簡單的,但我更喜歡利用 Scala 是一種函數式語言的事實,並將你的函數用作一等公民:

sc.textFile("/home/ubuntu/data.txt",4).map { text =>
  val punctPattern = "[^a-zA-Z0-9\\s]".r
  punctPattern.replaceAllIn(text, "").toLowerCase
}

或者,如果您真的想將事情分開:

val removePunctuation: String => String = (text: String) => {
  val punctPattern = "[^a-zA-Z0-9\\s]".r
  punctPattern.replaceAllIn(text, "").toLowerCase
}
sc.textFile("/home/ubuntu/data.txt",4).map(removePunctuation)

這些選項當然有效,因為正如您應該確認的那樣, Regex 是可序列化的

在次要但非常重要的注意事項中,構建Regex是昂貴的,因此為了性能,將其從轉換中排除 - 可能使用廣播

閱讀堆棧跟蹤,有:

$outer,類型:A$A21$A$A21 類

這是一個很好的提示。 您的 lambda 是可序列化的,但您的類不可序列化。

當您創建 lambda 表達式時,此表達式將引用外部類。 您的情況下的外部類不可序列化,即未實現 Serializable 或其中一個字段不是 Serializable 的實例

避免序列化問題的示例https://github.com/walter1978/spark_examples

暫無
暫無

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

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