繁体   English   中英

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

[英]spark (java) - Too many open files

我正在尝试在 spark2 中运行一个批处理作业,它将一个巨大的列表作为输入并在列表上迭代以执行处理。 该程序对列表的大约 8 000 条记录执行良好,然后中断给出异常:

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)

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

尝试设置spark.shuffle.consolidateFilestrue的SparkConf。 但这没有用。

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

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

一般来说,如果您的集群具有:

assigned cores = `n`; 

你运行一个工作:

reducers = `k`

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

默认 ulimit 为: 1024 ,这对于大型应用程序来说太低了。

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

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

请参阅这些文件以获取相同信息:

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

当我在同一个流上应用两个foreachRDD()时,我遇到了同样的问题。 第一种方法将事件发布到 Kafka 主题,第二种方法将输出写入 HDFS。

    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")
    })

我在同一个foreachRDD()组合了两个输出,并在 RDD 上应用了cache()操作。

    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()

    })

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM