使用NotSerializableException

时间:2016-02-20 06:17:35

标签: scala apache-spark

下面是我用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”))

我想知道确切的根本原因以及以下内容。

  1. 是否需要序列化从spark上下文调用的每个类?
  2. 每个定义的方法是否需要序列化为字节并通过节点发送?。
  3. 所调用的RDD的封闭类是否需要序列化?。
  4. 根据我的理解,转换函数是通过节点发送的。所以这些方法是序列化的。编写的新方法怎么样?。
  5. 任何帮助表示感谢。

2 个答案:

答案 0 :(得分:2)

您可以使Anagram类可序列化,或将verifyAnagrams函数移动到对象。在scala中object内声明的函数等同于java静态方法,因此不需要对它们进行序列化。

另请阅读Spark应用程序中的my blog post about using non-serializable objects

答案 1 :(得分:0)

将您的函数verifyAnagrams移动到Object而不是类。