Apache Spark映射函数org.apache.spark.SparkException:任务不可序列化

时间:2018-10-18 15:39:23

标签: apache-spark java-8 sparkcore

我正在学习Apache Spark,并且正在使用Java 8和Spark Core 2.3.2。

我发现当我在RDD上使用map函数时,它仅在使用Lambda表达式时有效。

这可行:

JavaRDD<Integer> rdd = sc.parallelize(Arrays.asList(1, 2, 3, 4));
JavaRDD<Integer> result = rdd.map(x -> x*x );

但这不会,并引发org.apache.spark.SparkException:任务无法序列化

JavaRDD<Integer> result = rdd.map(new Function<Integer, Integer>() {
    public Integer call(Integer x) { return x*x; }
});

有人可以解释为什么吗? 谢谢

1 个答案:

答案 0 :(得分:1)

当您声明new Function时,它包含对包含它的类的引用。当Spark尝试将新的匿名Function实例发送给工作程序时,它也尝试对包含的类进行序列化,但是显然,该类未实现Serializable或具有其他不可序列化的成员。您可能会遇到类似object not serializable (class: YourClass, value: YourClass@e49bf8a)的错误,其中“ YourClass”是包含Function声明的类。

如果您改为将Function声明为类的静态成员,则:

static Function<Integer, Integer> f = new Function<Integer, Integer>() {
    public Integer call(Integer x) {
        return x * x;
    }
};

并将其传递给您的map函数:

JavaRDD<Integer> result = rdd.map(f);

那么您可能会好起来的。我通常会尝试将要在此类转换中使用的所有函数声明为静态(如果它们太大而无法使用lambda形式),因此我不会在偶然的情况下意外地序列化整个类一个功能。