spark(java) - 太多打开的文件

时间:2017-06-22 12:43:24

标签: apache-spark

我正在尝试在spark2中运行一个批处理作业,它将一个巨大的列表作为输入并在列表上进行迭代以执行处理。程序对列表中的大约8 000条记录执行正常,然后打破例外:

mod_ws_proxy

neo4j数据库用作输入。我正在从neo4j读取300k节点作为输入,并在输入rdd上执行for循环。

在SparkConf中尝试将WARN Lost task 0.0 in stage 421079.0 (TID 996338, acusnldlenhww4.cloudapp.net, executor 1): java.io.FileNotFoundException: /data/1/hadoop/yarn/local/usercache/A2159537-MSP01/appcache/application_1497532405817_0072/blockmgr-73dc563c-8ea5-4f2d-adfe-6c60cf3e3968/0d/shuffle_145960_0_0.index.cfb6d5ea-8c7b-41a1-acc3-2c840e7f8998 (Too many open files) at java.io.FileOutputStream.open0(Native Method) at java.io.FileOutputStream.open(FileOutputStream.java:270) at java.io.FileOutputStream.<init>(FileOutputStream.java:213) at java.io.FileOutputStream.<init>(FileOutputStream.java:162) at org.apache.spark.shuffle.IndexShuffleBlockResolver.writeIndexFileAndCommit(IndexShuffleBlockResolver.scala:144) at org.apache.spark.shuffle.sort.BypassMergeSortShuffleWriter.write(BypassMergeSortShuffleWriter.java:128) at org.apache.spark.scheduler.ShuffleMapTask.runTask(ShuffleMapTask.scala:96) at org.apache.spark.scheduler.ShuffleMapTask.runTask(ShuffleMapTask.scala:53) at org.apache.spark.scheduler.Task.run(Task.scala:99) at org.apache.spark.executor.Executor$TaskRunner.run(Executor.scala:322) 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) (org.apache.spark.scheduler.TaskSetManager) 设置为spark.shuffle.consolidateFiles。但这没有用。

2 个答案:

答案 0 :(得分:1)

如果可能的话,增加ulimit - 以克服这一点。

减少每个节点使用的reducer或core的数量。但它对你的工作有一些性能影响。

通常,如果您的群集有:

assigned cores = `n`; 

你用:

开始工作
reducers = `k`

然后Spark将并行打开n * k个文件并开始编写。

默认的ulimit是:1024,对于大型应用来说太低了。

使用ulimit -a查看当前最大打开文件数。

我们可以暂时改变打开文件的数量;通过更新系统配置文件。

请参阅以下文件:

/etc/sysctl.conf
/etc/security/limits.conf

答案 1 :(得分:0)

当我在同一流上应用两个 stream.foreachRDD(rdd => { val spark = SparkSession.builder.config(rdd.sparkContext.getConf).getOrCreate() val batchDF = spark.createDataFrame(rdd, batchOutputSchema) // Publish to kafka batchDF .write.format("kafka") .option("kafka.bootstrap.servers", bootstrapServer) .option("topic", "topic_name") .save() }) stream.foreachRDD(rdd => { val spark = SparkSession.builder.config(rdd.sparkContext.getConf).getOrCreate() val batchDF = spark.createDataFrame(rdd, batchOutputSchema) // Write the output into HDFS batchDF .write.mode("append") .parquet("/path") }) 时,我遇到了同样的问题。第一种方法将事件发布到Kafka主题,第二种方法将输出写入HDFS。

foreachRDD()

我将两个输出合并在同一个cache()中,并在RDD上应用了 stream.foreachRDD(rdd => { val spark = SparkSession.builder.config(rdd.sparkContext.getConf).getOrCreate() val batchDF = spark.createDataFrame(rdd, batchOutputSchema).cache() // Write into HDFS batchDF .write.mode("append") .parquet("/path") // Publish to Kafka batchDF .write.format("kafka") .option("kafka.bootstrap.servers", bootstrapServer) .option("topic", "topic_name") .save() }) 操作。

const newArray = oldArray.map( str => str.substr(0,2) );