【问题标题】:Spark: .saveAsTextFile losing inherited field for the Java objectSpark:.saveAsTextFile 丢失 Java 对象的继承字段
【发布时间】:2016-04-20 08:05:27
【问题描述】:

我有以下课程:

public final class Derived extends AbstractBase implements Serializable {

    private static final long serialVersionUID = 1L;
    private String fieldA
       :
}

public abstract class AbstractBase {

    protected List<String> sources = new ArrayList<String>();

    public final String toJsonString() {
        return (new Gson()).toJson(this);
    }

    @Override
    public final String toString() {
        return toJsonString();
    }

    :
}

然后在我的 Spark 工作中:

 val myRDD: RDD[Derived] = input.map {
     ...
 }.saveAsTextFile("myOutput")

myOutput 文件中每个Derived 对象的Json 字符串总是缺少sources 列表。但是,如果我手动移动

protected List<String> sources = new ArrayList<String>();

AbstractBaseDerived 类,一切正常。

有人知道为什么在 Spark - saveAsTextfile 方法中缺少继承字段吗?

谢谢!

【问题讨论】:

  • 你有复制器吗?我不认为这是saveAsTextFile 的问题。您可以使用collect().foreach(println) 来检查它是否输出相同的结果。

标签: java scala inheritance apache-spark derived-class


【解决方案1】:

RDD 写入文本文件时,它不会使用Java 序列化,而只会在每条记录上调用toString。见例子:

case class A (i:Int,s:String) extends Serializable { override def toString = "po"}
val r = sc.parallelize(Seq( A(1,"a"), A(2,"b")))
r.saveAsTextFile("/tmp/f2")
 // hadoop fs -cat /tmp/f2/part* will give "po","po"
 // same but no overriding toString
case class B (i:Int,s:String) extends Serializable
val r = sc.parallelize(Seq( A(1,"a"), A(2,"b")))
r.saveAsTextFile("/tmp/f2")
// result B(1,a) B(2,b)

请注意,如果您使用 saveAsObjectFile,它将使用 Java 序列化,但该格式对非 Java 程序不太友好,并且有其自身的缺点(例如,它比 Kryo 更慢且占用更多空间)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-20
    • 1970-01-01
    • 1970-01-01
    • 2020-10-25
    相关资源
    最近更新 更多