我正在使用带有Scala插件和spark库的IntelliJ社区版。我还在学习Spark并且正在使用Scala工作表。
我编写了以下代码,用于删除字符串中的标点符号:
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.RDDOperationScope $ .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,名称:$ outer,类型:A $ A21 $ A $ A21) - 对象(A $ A21 $ A $ A21 $$ anonfun $ words $ 1,) 在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) 在org.apache.spark.SparkContext.clean(SparkContext.scala:2094) 在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.apache.spark.rdd.RDD.withScope(RDD.scala:362) 在org.apache.spark.rdd.RDD.map(RDD.scala:369) 在A $ A21 $ A $ A21.words $ lzycompute(Test.sc:27) 在A $ A21 $ A $ A21.words(Test.sc:27) at A $ A21 $ A $ A21.get $$ instance $$ words(Test.sc:27) 在A $ A21 $ .main(Test.sc:73) 在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) 在org.jetbrains.plugins.scala.worksheet.MyWorksheetRunner.main(MyWorksheetRunner.java:22)
答案 0 :(得分:5)
正如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
}
}
答案 1 :(得分:5)
正如@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
is serializable,因为您应该确认。
在次要但非常重要的说明中,构建Regex
代价很高,因此为了提高性能而将其从转换中分解出来 - 可能使用broadcast。
答案 2 :(得分:2)
阅读stacktrace,有:
$ outer,类型:A $ A21 $ A $ A21
这是一个非常好的提示。您的lambda是可序列化的,但您的类不可序列化。
当你创建lambda表达式时,这个表达式引用了外部类。您的案例中的外类不可序列化,即未实现Serializable或其中一个字段不是Serializable的实例