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

Apache Spark map function org.apache.spark.SparkException: Task not serializable

我正在学习 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; }
});

谁能解释一下为什么? 谢谢

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

如果您改为将函数声明为 class 的静态成员:

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

并将其传递给您的地图函数:

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

那么你可能会没事的。我通常会尝试将我将在转换中使用的所有函数都声明为静态的(如果它们太大而无法使用 lambda 形式),所以我不会不小心结束整个序列化 class当我只想要一个功能时。