@yanbo-ai
2014-11-04T16:16:14.000000Z
字数 2131
阅读 11379
Spark
General
Troubleshooting
TooManyOpenFiles
当你在 Linux 系统上使用 SparkContext.textFile
加载本地文件系统(文件目录)的数据时,可能会遇到下面的错误:
14/11/04 15:38:59 WARN TaskSetManager: Lost task 99.0 in stage 2.0 (TID 100, spark-test): java.io.FileNotFoundException: /tmp/spark-local-20141104153618-ee2b/13/shuffle_0_99_513 (Too many open files)
java.io.FileOutputStream.open(Native Method)
java.io.FileOutputStream.<init>(FileOutputStream.java:221)
org.apache.spark.storage.DiskBlockObjectWriter.open(BlockObjectWriter.scala:123)
org.apache.spark.storage.DiskBlockObjectWriter.write(BlockObjectWriter.scala:192)
org.apache.spark.shuffle.hash.HashShuffleWriter$$anonfun$write$1.apply(HashShuffleWriter.scala:67)
org.apache.spark.shuffle.hash.HashShuffleWriter$$anonfun$write$1.apply(HashShuffleWriter.scala:65)
scala.collection.Iterator$class.foreach(Iterator.scala:727)
org.apache.spark.util.collection.AppendOnlyMap$$anon$1.foreach(AppendOnlyMap.scala:159)
org.apache.spark.shuffle.hash.HashShuffleWriter.write(HashShuffleWriter.scala:65)
org.apache.spark.scheduler.ShuffleMapTask.runTask(ShuffleMapTask.scala:68)
org.apache.spark.scheduler.ShuffleMapTask.runTask(ShuffleMapTask.scala:41)
org.apache.spark.scheduler.Task.run(Task.scala:54)
org.apache.spark.executor.Executor$TaskRunner.run(Executor.scala:177)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
java.lang.Thread.run(Thread.java:724)
这是由于程序打开的文件句柄数超过了 Linux 系统的限制,注意看下面的代码片段:
val tradeDir = "/data/trades"
val userPairsRDD = sc.textFile(tradeDir).map(line => (line.split('\001')(4) -> 1))
val userCountsWithReduce = userPairsRDD
.reduceByKey(_ + _)
.collect()
textFile
函数的传入参数如果是一个文件夹,它会试图加载文件夹里面所有的文件数据到内存中。当文件夹里的文件数量大于操作系统所限制打开的文件数量时就会出现上述错误。
有几种方法可以确认文件夹下的文件数量:
ls | wc -l
14/11/04 15:45:59 INFO TaskSetManager: Finished task 129.0 in stage 0.0 (TID 129) in 5878 ms on spark-test (128/1033)
修复上述错误的建议:
ulimit -a
查看限制打开文件数据的设置。spark-env.sh
上设置一个较大的文件打开限制,像这样:ulimit -n 10240
* soft nofile 10240
* hard nofile 10240
注意:使用设置 /etc/security/limits.conf 改变打开文件限制时需要退出登录然后重新登录才有效。