我在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();
}
}
如何解决此错误? 提前谢谢。
答案 0 :(得分:12)
显然Rating
不能是Serializable
,因为它包含对Spark结构(即SparkSession
,SparkConf
等)的引用作为属性。
问题在于
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;
祝你好运。