任务不可序列化 - Spark Java

时间:2016-11-08 06:26:35

标签: java serialization apache-spark

我在Spark中遇到Task not serializable错误。我已经搜索并尝试使用某些帖子中建议的静态函数,但它仍然会出现相同的错误。

代码如下:

public class Rating implements Serializable {
    private SparkSession spark;
    private SparkConf sparkConf;
    private JavaSparkContext jsc;
    private static Function<String, Rating> mapFunc;

    public Rating() {
        mapFunc = new Function<String, Rating>() {
            public Rating call(String str) {
                return Rating.parseRating(str);
            }
        };
    }

    public void runProcedure() { 
        sparkConf = new SparkConf().setAppName("Filter Example").setMaster("local");
        jsc = new JavaSparkContext(sparkConf);
        SparkSession spark = SparkSession.builder().master("local").appName("Word Count")
            .config("spark.some.config.option", "some-value").getOrCreate();        

        JavaRDD<Rating> ratingsRDD = spark.read().textFile("sample_movielens_ratings.txt")
                .javaRDD()
                .map(mapFunc);
    }

    public static void main(String[] args) {
        Rating newRating = new Rating();
        newRating.runProcedure();
    }
}

错误给出: enter image description here

如何解决此错误? 提前谢谢。

2 个答案:

答案 0 :(得分:12)

显然Rating不能是Serializable,因为它包含对Spark结构(即SparkSessionSparkConf等)的引用作为属性。

问题在于

JavaRDD<Rating> ratingsRD = spark.read().textFile("sample_movielens_ratings.txt")
            .javaRDD()
            .map(mapFunc);

如果查看mapFunc的定义,则会返回Rating个对象。

mapFunc = new Function<String, Rating>() {
    public Rating call(String str) {
        return Rating.parseRating(str);
    }
};

此功能用于map(Spark术语中的转换)。由于转换直接执行到工作节点而不是驱动程序节点,因此它们的代码必须可序列化。这迫使Spark尝试序列化Rating类,但这是不可能的。

尝试从Rating中提取所需的功能,并将它们放在不具有任何Spark结构的其他类中。最后,使用此新类作为mapFunc函数的返回类型。

答案 1 :(得分:2)

此外,您必须确保不包含不可序列化的变量,例如 JavaSparkContext SparkSession 。如果你需要包含它们,你应该这样定义:

private transient JavaSparkContext sparkCtx;
private transient SparkSession spark;
祝你好运。