当前位置: 首页 > 知识库问答 >
问题:

使用Java实现Apache Spark对象序列化

汪典
2023-03-14

我正在尝试准备一个库(用Java编写)来运行在Apache-Spark上。由于该库有数百个类,并且仍处于活跃的开发阶段,所以我不想一一序列化所有的类。相反,我搜索了另一个方法,并找到了这个方法,但它同样不能解决序列化问题。

下面是代码示例:

    List<Integer> data = Arrays.asList(1,2,3,4,5,6);
    JavaRDD<Integer> distData = sc.parallelize(data);
    JavaRDD<Year4D> years = distData.map(y -> func.call(y));
    List<Year4D> years1 = years.collect();
    private static Function<Integer, Year4D> func = new Function<Integer, Year4D>() {
    public Year4D call(Integer arg0) throws Exception {
        return new Year4D(arg0);
    }};
public class Year4D{
private int year = 0;
public Year4D(int year) {
    if (year < 1000) year += (year < 70) ? 2000 : 1900;
    this.year = year;
}
public String toString() {
    return "Year4D [year=" + year + "]";
}}

这会产生年份4d的“对象不可序列化”异常:

Job aborted due to stage failure: Task 6.0 in stage 0.0 (TID 6) had a not serializable result...

顺便说一下,如果我将命令Action collect()替换为foreach(func),

那么,我的问题是为什么collect()不起作用?

共有1个答案

孟嘉歆
2023-03-14

解决方案1(您不会使用它,因为通过使类实现Serializable来修改每个类更容易):创建实现Serializable并覆盖其WriteObjectReadObject方法的包装类

public class Year4DWraper implements Serializable{

    private Year4D year4d;

    public Year4DWraper(Year4D year4d) {
        this.year4d = year4d;
    }
    public Year4D getYear4D(){
        return yeard4D;
    }

    private void writeObject(ObjectOutputStream os)
            throws IOException {
       os.writeInt(year4D.getYear());

    }

    private void readObject(ObjectInputStream is)
            throws IOException, ClassNotFoundException {
       int year = is.readInt();
       year4D = new Yeard4D(year);
    }

}

解决方案2:使用Kyro为您进行序列化/反序列化

SparkConf conf = new SparkConf();
conf.set("spark.kryo.registrator", "org.apache.spark.examples.MyRegistrator");
...

public class MyRegistrator implements KryoRegistrator {
    public void registerClasses(Kryo kryo) {
        kryo.register(Year4D.class);
    }
}

建议类包含一个无参数的构造函数。

如果您对Kyro默认提供的seriliazers不满意,或者您有复杂的类,您可以始终定义自己的类。

 类似资料:
  • 我们需要在Java应用程序中集成OData服务。由于缺少SDL/OData文档,我们决定使用Apache Olingo。 我的问题是:如何将接收到的数据反序列化为真实对象?是否有一种方法(OData4)使用带注释的类(如Jpa或JSON/Jackson)直接反序列化为类? 我发现的示例没有使用特定的类,而是使用字符串文本来声明字段名。这是唯一的办法吗?有没有一个例子至少有OData交付的每个实体的

  • 问题内容: 我想将此对象序列化为JSON字符串 并获得如下结果: 我尝试使用 但是相反,我得到了: 人员序列化器: 欢迎任何建议 谢谢,马里奥 问题答案: 为了获得所需的结果,您需要像这样编写串行器: 的结果 将会 完整的代码:

  • 我想将这个对象序列化为JSON字符串 并得到如下结果: 我试着用 但不是这样,我得到了: 个性化序列化: 欢迎提出任何建议 谢谢,马里奥

  • 我试图序列化一个对象数组,并将其写入一个名为address.ser的文件,然后从该文件中读取,反序列化对象数组并显示其属性。我尝试一次序列化整个arrayList(读取时在单个会话中反序列化它),也尝试一个接一个地序列化对象数组的每个对象(读取时一个接一个地反序列化它)。问题是,当从address.ser文件读回来时,我只得到最后一个被写入的对象的数据,而不是其他的。 以下是代码片段: 这是用于将

  • 给定一个包含以下格式数据的大文件(V1,V2,…,VN) 我正在尝试使用Spark获得一个类似于下面的配对列表 我尝试了针对一个较旧的问题所提到的建议,但我遇到了一些问题。例如, 我得到了错误, 有人能告诉我哪些地方我可能做得不对,或者有什么更好的方法可以达到同样的效果?非常感谢。

  • 问题内容: 问题在于,每次执行main方法时,a.xml的旧内容都会丢失,并被新的内容替代。如何在不丢失先前信息的情况下将内容附加到a.xml文件? 问题答案: 样例代码