gpt4 book ai didi

java - 映射 JavaRDD 时获取 java.io.NotSerializableException

转载 作者:行者123 更新时间:2023-11-29 06:53:14 25 4
gpt4 key购买 nike

以下是当我尝试将作业分派(dispatch)给执行程序时导致 java.io.NotSerializableException 的代码。

    JavaRDD<Row> rddToWrite = dataToWrite.toJavaRDD();
JavaRDD<String> stringRdd = rddToWrite.map(new Function<Row, String>() {

/**
* Serial Version Id
*/
private static final long serialVersionUID = 6766320395808127072L;

@Override
public String call(Row row) throws Exception {
return row.mkString(dataFormat.getDelimiter());
}
});

但是,当我执行以下操作时,任务序列化成功:

JavaRDD<Row> rddToWrite = dataToWrite.toJavaRDD();
List<String> dataList = rddToWrite.collect().stream().parallel()
.map(row -> row.mkString(dataFormat.getDelimiter()))
.collect(Collectors.<String>toList());
JavaSparkContext javaSparkContext = new JavaSparkContext(sessionContext.getSparkContext());
JavaRDD<String> stringRDD = javaSparkContext.parallelize(dataList);

谁能帮我指出我在这里做错了什么?

编辑:dataFormat 是编写包含此代码的函数的类中的私有(private)成员字段。它是 DataFormat 类的一个对象,该类定义了两个字段,即 spark 数据格式(例如“com.databricks.spark.csv”)和分隔符(例如“\t”)。

最佳答案

new Function ...创建的匿名类需要引用封闭实例,序列化函数需要序列化封闭实例,包括dataFormat 所有其他领域。如果该类未标记为 Serializable,或具有任何不可序列化的非 transient 字段,它将无法工作。即使它这样做了,它也会悄悄地表现得比必要的更糟。

不幸的是,要完全解决这个问题,您需要创建一个命名的静态内部类(或只是一个单独的类),它甚至不能是本地的(因为匿名和 local classes in Java 都不能是静态的):

static class MyFunction extends Function<Row, String> {
private String delimiter;
private static final long serialVersionUID = 6766320395808127072L;

MyFunction(String delimiter) {
this.delimiter = delimiter;
}

@Override
public String call(Row row) throws Exception {
return row.mkString(delimiter);
}
}

然后

JavaRDD<String> stringRdd = rddToWrite.map(new MyFunction(dataFormat.getDelimiter()));

关于java - 映射 JavaRDD 时获取 java.io.NotSerializableException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40838697/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com