下面是我用scala编写的spark程序,用于查找给定单词的字谜。但是从测试用例执行时程序失败了。
class Anagram {
def collectAnagrams(name: String,rdd : RDD[String]): RDD[String] = {
return rdd.flatMap(line => line.split("\\s+")).filter(x=>verifyAnagrams(x,name));
}
def verifyAnagrams(str1 : String, str2 : String): Boolean = {
if(str1.length != str2.length) {
return false;
}
val letters = Array.fill[Int](256)(0);
for(i <- 0 until str1.length) {
letters(str1.charAt(i).toInt)+=1;
letters(str2.charAt(i).toInt)-=1;
}
for(i <-0 until 256) {
if(letters(i) != 0) {
return false;
}
}
return true;
}
}
class AnagramTest extends FunSuite with BeforeAndAfter {
var sc: SparkContext = _
before {
val conf = new SparkConf().setMaster("local").setAppName("anagarm of string")
sc = new SparkContext(conf)
}
test("Anagram string check in a file") {
val anagramToken : String = "Tunring"
// @@ SETUP
val Anagram = new Anagram()
// @@ EXERCISE
val anagrams = Anagram.collectAnagrams(anagramToken,sc.textFile(getClass.getClassLoader.getResource("word_count_input.txt").getPath))
// @@ VERIFY
assert(anagrams.collect().toSet.size == 1)
}
}
执行上述测试用例时,会发生以下异常
任务不可序列化org.apache.spark.SparkException:任务不可序列化 org.apache.spark.util.ClosureCleaner $ .ensureSerializable(ClosureCleaner.scala:166) 在 org.apache.spark.util.ClosureCleaner $清洁机壳(ClosureCleaner.scala:158) 在org.apache.spark.SparkContext.clean(SparkContext.scala:1623)at org.apache.spark.rdd.RDD.filter(RDD.scala:303)at Anagram.collectAnagrams(Anagram.scala:10)** assert(anagrams.collect()。toSet == Set(“Tunring”,“Tunring”))
我想知道确切的根本原因以及以下内容。
任何帮助表示感谢。
答案 0 :(得分:2)
您可以使Anagram
类可序列化,或将verifyAnagrams
函数移动到对象。在scala中object
内声明的函数等同于java静态方法,因此不需要对它们进行序列化。
另请阅读Spark应用程序中的my blog post about using non-serializable objects。
答案 1 :(得分:0)
将您的函数verifyAnagrams
移动到Object而不是类。