2015-05-04 34 views
2

我有一個電影,有一個標題。在這個標題是電影的一年,如「電影(年)」。我想提取年份,我正在使用一個正則表達式。任務不可序列化 - 正則表達式

case class MovieRaw(movieid:Long,genres:String,title:String) 
case class Movie(movieid:Long,genres:Set[String],title:String,year:Int) 
val regexYear = ".*\\((\\d*)\\)".r 
moviesRaw.map{case MovieRaw(i,g,t) => Movie(i,g,t,t.trim() match { case regexYear(y) => Integer.parseInt(y)})} 

當執行的最後一個命令我碰到下面的錯誤:

java.io.NotSerializableException: org.apache.spark.SparkConf

運行在Spark /斯卡拉REPL,這個SparkContext: val conf = new SparkConf(true).set("spark.cassandra.connection.host", "localhost") val sc = new SparkContext(conf)

回答

2

正如Dean解釋的那樣,問題的原因是REPL從添加到REPL的代碼中創建了一個類,在這種情況下,同一上下文中的其他變量正在被關閉中「拉」正則表達式聲明。

考慮到要創建的上下文的方式,一個簡單的方法來避免序列化問題將申報SparkConfSparkContext瞬態:

@transient val conf = new SparkConf(true).set("spark.cassandra.connection.host", "localhost") 
@transient val sc = new SparkContext(conf) 

你甚至都不需要重新火花背景在REPL用於連接到卡桑德拉的唯一目的:

spark-shell --conf spark.cassandra.connection.host=localhost 
1

你可能有這樣的代碼在一個更大的Scala類或對象(一種類型)中,對嗎?如果是這樣,爲了序列化regexYear,整個封閉類型被序列化,但您可能已經在該類型中定義了SparkConf

這是一個非常常見和令人困惑的問題,並且正在努力防止它,因爲JVM和其上的語言(如Java)的限制。

溶液(現在)是把regexYear的方法或另一對象內:

object MyJob { 
    def main(...) = { 
    case class MovieRaw(movieid:Long,genres:String,title:String) 
    case class Movie(movieid:Long,genres:Set[String],title:String,year:Int) 
    val regexYear = ".*\\((\\d*)\\)".r 
    moviesRaw.map{case MovieRaw(i,g,t) => Movie(i,g,t,t.trim() match { case  regexYear(y) => Integer.parseInt(y)})} 
    ... 
    } 
} 

... 
object small { 
    case class MovieRaw(movieid:Long,genres:String,title:String) 
    case class Movie(movieid:Long,genres:Set[String],title:String,year:Int) 
    val regexYear = ".*\\((\\d*)\\)".r 
    moviesRaw.map{case MovieRaw(i,g,t) => Movie(i,g,t,t.trim() match { case regexYear(y) => Integer.parseInt(y)})} 
} 

希望這有助於。

+0

mh,即時通訊在scala repl上使用它,而不是在應用程序中。 Sry,忘了提到這一點。包裝在一個物體中可能是一個解決方案,但也許有更順利的方法來解決這個問題。 – mniehoff

+0

@mniehoff您是否在REPL上創建了自己的'SparkConf'?如果是這樣,你可以將這部分代碼添加到問題中嗎? – maasg

+0

將它添加到上面的問題。 – mniehoff

1

嘗試通過在卡桑德拉選項在命令行上的火花外殼是這樣的:

spark-shell [other options] --conf spark.cassandra.connection.host=localhost 

而且這樣你就不必重新創建SparkContext - 您可以使用獲取與火花殼自動實例化的SparkContext(SC)。