2017-04-08 83 views
1

我有一個「任務不可序列」異常當我運行火花Scala的程序與火花Scala編程爲不序列化的對象和功能

  • 火花RDDS不是可序列化的類型(java類)
  • 稱爲功能從沒有序列化的類(Java類,再次)

我的代碼是這樣的

object Main{ 
    def main(args : Array(String){ 
     ... 
     var rdd = sc.textFile(filename) 
        .map(line => new NotSerializableJClass(line)).cache() 
     //rdd is RDD[NotSerializableJClass] 
     ... 
     var test = new NotSerializableJPredicate() 
     rdd = rdd.filter(elem => test.test(elem)) 
     //throws TaskNotSerializable on test Predicate class 
    } 
} 

我注意到,我可以

rdd = rdd.filter(elem => (new NotSerializableJPredicate()).test(elem)) 

解決第二個部分,但我仍然拿到異常的類RDDS對象。另一種方式也是另一種方式,因爲我不想創建大量的PredicateClass對象。

你能幫我嗎?我如何繼續使用不可序列化的類?

+0

「NotSerializableJClass」是您的應用程序中定義的第三方類還是類? – himanshuIIITian

回答

1

RDD必須是可序列化的,因此您無法創建非序列化類的RDD。

對於您的謂詞,您可以使用mapPartitions編寫它。

rdd.mapPartitions{ 
    part => 
    val test = new NotSerializableJPredicate() 
    part.filter{elem => test.test(elem)} 
    } 

mapPartitons將每個分區運行一次,所以它可以讓你實例化的執行非序列化類,但只需要每個分區,而不是對每條記錄做一次。

0

一些可幫助我們避免任務序列化問題的一般規則:

如果要調用從代碼中任何類的方法;星火將需要序列包含method.Ways去全班around可以是以下任何一個: a>將方法聲明爲NotSerializableClass中的函數變量;所以不要寫: def foo(x:Int)= {blah blah}嘗試使用val foo =(x:Int)=> {blah blah} 所以;火花不再需要現在序列化整個班級。 b>重構代碼以提取單獨的類中的相關部分可能是在某些情況下要走的路。 c>將作業中實際上不需要的對象標記爲@transient並標記類可序列化