2016-09-19 27 views
0

我是Scala的新手。我在星火執行下面的代碼:org.apache.spark.SparkException:不能在scala中序列化的任務

scala> for(line <- sc.textFile("hdfs://ip:8020/property.conf")) 
     { 
      val c = line.split("=") 
      SparkConf.set(c(0), c(1)) 
      //println(c(0)+" "+c(1)) //Commented 
     } 

如果我刪除評論部分和評論SparkConf.set(c(0), c(1))然後正常工作和顯示數據。

但是在這種情況下,我想在運行時將參數設置爲SparkConf。 但它引發我錯誤

org.apache.spark.SparkException:任務不可序列

請建議我一些東西。

+0

我在谷歌搜索。但沒有發現任何特定的事情。有什麼辦法可以序列化這個 – Darshan

回答

2

對於瞭解spark而言非常重要的一件事是它是一個分佈式環境。

名稱RDDResilient Distributed Datasets的縮寫。火花RDD中的項一般分爲partitions,分佈在Spark集羣中的各個不同節點上。

當你調用像yourRdd.map(a => a.toString),該map實現這個RDD的知道,它必須首先把這個包a => a.toString功能的關閉,然後序列化閉合,然後將其發送到有該RDDpartitions的所有節點。結果的實際計算髮生在這些節點上。

所以......當你在處理RDD的時候,請確保你不會混淆/混合使用分配RDD api和普通的Scala API。

推薦的方法給你寫一段代碼會,

val yourRdd = sc.textFile("hdfs://ip:8020/property.conf")) 

yourRdd.foreach(line => 
    val c = line.split("=") 
    println(c(0) + " " + c(1)) 
) 
SparkConf.set(c(0), c(1))

這裏,SparkConfclass,你通常不能序列classes。您也不能在class SparkConf上調用成員函數set。您需要創建classes的實例。另外SparkConf碰巧是一個沒有實現可序列化接口的類,因此即使SparkConf的實例也是不可序列化的。

通常情況下,您不應該使用火花RDD來創建您的SparkConf,因爲RDD不會在沒有SparkContext的情況下存在,而這又需要SparkConf進行初始化。

但是對於這種情況可以說你需要這麼做......然後你首先從你的RDD獲得一個正常的scala列表然後用它來創建你的SparkConf。

val mySparkConf = new SparkConf() 

val yourRdd = sc.textFile("hdfs://ip:8020/property.conf")) 

val yourList = yourRdd.foreach(line => 
    val c = line.split("=") 
).collect.toList 

yourList.foreach(c => mySparkConf.set(c(0), c(1))) 
+0

非常感謝你提供的信息。但是當我正在編寫SparkConf.set(c(0),c(1))在forech中時。那麼它會拋出我錯誤的org.apache.spark.SparkException:任務不可序列化 你知道爲什麼會發生這種情況嗎? – Darshan

+0

正如我所說...功能需要序列化之前發送到相應的節點。因此函數不應該有任何不能被序列化的東西,'SparkConf'恰好就是這樣的事情之一。 –

相關問題