Apache Spark:手动构建的RDD的spark-shell中的“SparkException:Task not serializable”

时间:2015-08-25 12:10:59

标签: serialization apache-spark rdd

我有以下代码来检测事件中最常用的顶级域名。 我用它来通过Spark SQL获取日期。

功能本身经过测试并正常运行。我使用Amazon EMR和spark-shell。当spark几乎立即向节点发送任务时,我收到一个长堆栈跟踪,并且最终没有任何具体的“SparkException:Task not serializable”。这是什么交易?

import scala.io.Source
val suffixesStr = 
    Source.fromURL("https://publicsuffix.org/list/public_suffix_list.dat").mkString
val suffList = 
    suffixesStr.lines.filter(line => !line.startsWith("//") && line.trim() != "")
val suffListRDD = sc.parallelize(suffList.toList).collect()

 val cleanDomain = (domain: String) => {
  var secLevelSuffix = 
    suffListRDD.find(suffix => domain.endsWith("."+suffix) && suffix.contains("."))
  var regex = """[^.]+\.[^.]+$""".r
  if (!secLevelSuffix.isEmpty){
    regex = """[^.]+\.[^.]+\.[^.]+$""".r
  }
  var cleanDomain = regex.findFirstMatchIn(domain).map(_ group 0)
  cleanDomain.getOrElse("")
}

val getDomain = (url: String) => {
  val domain = """(?i)^(?:(?:https?):\/\/)?(?:(?:www|www1|www2|www3)\.)?([^:?#/\s]+)""".r.findFirstMatchIn(url).map(_ group 1)
  var res = domain.getOrElse("")
  res = res.toLowerCase()
  if (res.contains("google.com")){
    res = res.replace("google.com.br", "google.com")
  }else{
    res = cleanDomain(res)
  }
  res
}

sqlContext.udf.register("getDomain", getDomain)
val domains = sqlContext.sql("SELECT count(*) c, domain from (SELECT getDomain(page_url) as domain FROM events) t group by domain order by c desc")
domains.take(20).foreach(println)

1 个答案:

答案 0 :(得分:0)

当您以编程方式定义RDD时,请不要忘记将不会复制到工作节点的内容标记为 @transient

在你的情况下:

@transient val suffixesStr = ...
@transient val suffList = ...