计算大文件时Spark会崩溃

时间:2016-10-20 10:13:26

标签: scala debugging hadoop apache-spark

我在Scala中有一个程序读取CSV文件,向Dataframe添加一个新列并将结果保存为镶木地板文件。它适用于小文件(< 5 Go),但是当我尝试使用更大的文件(~80 Go)时,它总是会失败,因为它应该使用这个堆栈跟踪来编写镶木地板文件:

16/10/20 10:03:37 WARN scheduler.TaskSetManager: Lost task 14.0 in stage 4.0 (TID 886, 10.0.0.10): java.io.EOFException: reached end of stream after reading 136445 bytes; 1245184 bytes expected
  at org.spark_project.guava.io.ByteStreams.readFully(ByteStreams.java:735)
  at org.apache.spark.sql.execution.UnsafeRowSerializerInstance$$anon$3$$anon$1.next(UnsafeRowSerializer.scala:127)
  at org.apache.spark.sql.execution.UnsafeRowSerializerInstance$$anon$3$$anon$1.next(UnsafeRowSerializer.scala:110)
  at scala.collection.Iterator$$anon$12.next(Iterator.scala:444)
  at scala.collection.Iterator$$anon$11.next(Iterator.scala:409)
  at org.apache.spark.util.CompletionIterator.next(CompletionIterator.scala:30)
  at org.apache.spark.InterruptibleIterator.next(InterruptibleIterator.scala:43)
  at scala.collection.Iterator$$anon$11.next(Iterator.scala:409)
  at org.apache.spark.sql.catalyst.expressions.GeneratedClass$GeneratedIterator.processNext(Unknown Source)
  at org.apache.spark.sql.execution.BufferedRowIterator.hasNext(BufferedRowIterator.java:43)
  at org.apache.spark.sql.execution.WholeStageCodegenExec$$anonfun$8$$anon$1.hasNext(WholeStageCodegenExec.scala:370)
  at scala.collection.Iterator$$anon$11.hasNext(Iterator.scala:408)
  at org.apache.spark.shuffle.sort.UnsafeShuffleWriter.write(UnsafeShuffleWriter.java:161)
  at org.apache.spark.scheduler.ShuffleMapTask.runTask(ShuffleMapTask.scala:79)
  at org.apache.spark.scheduler.ShuffleMapTask.runTask(ShuffleMapTask.scala:47)
  at org.apache.spark.scheduler.Task.run(Task.scala:86)
  at org.apache.spark.executor.Executor$TaskRunner.run(Executor.scala:274)
  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
  at java.lang.Thread.run(Thread.java:745)

如果有人知道可能导致这种情况的原因,那将对我有所帮助!

使用的系统

  • Spark 2.0.1
  • Scala 2.11
  • Hadoop HDFS 2.7.3

所有在6个机器集群中的Docker中运行(每个4核和16个RAM)

示例代码

var df = spark.read.option("header", "true").option("inferSchema", "true").option("nullValue", "NULL").csv(hdfsFileURLIn)
df = df.withColumn("ipix", a2p(df.col(deName), df.col(raName)))
df.repartition(nPartitions, $"ipix").write.mode("overwrite").parquet(hdfsFileURLOut)

3 个答案:

答案 0 :(得分:1)

以下几点可能对您有所帮助:

  1. 我认为您应该检查ipix列数据的分布情况,可能会发生数据偏差,因此1个或几个分区可能比其他分区大得多。那些胖分区可能是这样的,1个正在处理胖分区的任务可能会失败。它可能与你的函数a2p的输出有关。即使没有重新分区,我也会首先测试运行此作业(只需删除此调用并尝试查看是否成功 - 如果没有重新分区调用,它将使用默认分区,可能按输入csv文件的大小分割)

  2. 我也希望您的输入csv不是gzip-ed(因为gzip-ed数据不能拆分,所以所有数据都在1个分区中)

答案 1 :(得分:0)

你能提供代码吗? 也许你写的代码是在驱动程序上运行的?你如何处理文件?

有一个处理大数据的特殊Spark功能,例如RDD。 一旦你这样做:

someRdd.collect()

您将rdd带到驱动程序内存中,因此不使用spark的功能。 处理大数据的代码应该在slave上运行。

请检查:differentiate driver code and work code in Apache Spark

答案 2 :(得分:0)

在YARN模式下解压缩混洗数据流时,问题似乎是读取失败。

尝试以下代码,看看它是怎么回事。

var df = spark.read.option("header", "true").option("inferSchema", "true").option("nullValue", "NULL").csv(hdfsFileURLIn)
df = df.withColumn("ipix", a2p(df.col(deName), df.col(raName))).persist(StorageLevel.MEMORY_AND_DISK)
df.repartition(nPartitions, $"ipix").write.mode("overwrite").parquet(hdfsFileURLOut)

还有一个类似的问题Spark job failing in YARN mode