2016-01-14 20 views
1

我有以下類別:星火:.saveAsTextFile失去繼承領域的Java對象

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(); 
    } 

    : 
} 

然後在我的星火工作:

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

每個Derived對象在MyOutput中文件JSON字符串總是缺少sources列表。但是,如果我手動從AbstractBase移動

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

Derived類,一切工作正常。

有誰知道爲什麼在Spark-saveAsTextfile方法中遺漏了一個字段?

謝謝!

+0

你有複製?我不認爲這是'saveAsTextFile'的問題。你可以使用'collect()。foreach(println)'來檢查它是否輸出相同的結果。 – zsxwing

回答

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程序,並配有其自身的缺點(它的速度較慢,需要更多的空間,然後KRYO,因爲它會使用Java序列化實例)