获取大输入文件时Spark OutOfMemoryError

时间:2016-09-30 16:59:03

标签: apache-spark

我有一个spark应用程序,它读取一个包含1亿行的文件(每行有一个代码,例如US1.234.567B1)并从中获取一些模式,如下所示:

  val codes = sc.textFile("/data/codes.txt")

  def getPattern(code: String) = code.replaceAll("\\d", "d")

  val patterns: RDD[(String, Int)] = codes
    .groupBy(getPattern)
    .mapValues(_.size)
    .sortBy(- _._2)

  patterns
    .map { case (pattern, size) => s"$size\t$pattern" }
    .saveAsTextFile("/tmp/patterns")

我在master = local [*]上运行它,但它失败了java.lang.OutOfMemoryError: GC overhead limit exceeded

为什么?

我认为Spark可以处理任何大小的输入,只要它有足够的硬盘空间。

2 个答案:

答案 0 :(得分:2)

总之,你试图使用Spark反模式:

.groupBy(getPattern)
.mapValues(_.size)

可以很容易地表达为例如:

codes.keyBy(getPattern).mapValues(_ => 1L).reduceByKey(_ + _).sortBy(_._2, false)
  

我认为Spark可以处理任何大小的输入。

只要你不能让它变得不可能,它通常可以扩展。 RDD上的group / groupByKey为每个密钥创建本地集合。其中每一个都在一个执行者的记忆中。

答案 1 :(得分:1)

是的spark可以处理非常大的文件,但并行的单位是执行者。 '内存不足错误'是因为火花执行器存储器或火花驱动器存储器不足。请尝试增加spark.executor.memory和spark.driver.memory,并在提交作业之前调整执行程序的数量。

您可以在属性文件或SparkConf中设置这些值,也可以在spark-submit期间直接在命令行中设置这些值。链接http://spark.apache.org/docs/latest/configuration.html