火花中止火花作业中打开的文件过多

时间:2018-11-16 05:15:39

标签: apache-spark amazon-s3 apache-spark-sql hadoop2 amazon-emr

在我的应用程序中,我正在读取40 GB的文本文件,该文件总共分布在188个文件中。 我使用rdd对拆分了这些文件并在spark中每行创建xml文件。 对于40 GB的输入,它将创建数百万个小型xml文件,这是我的要求。 一切正常,但是当spark将文件保存在S3中时,它将引发错误,并且作业失败。

这是我得到的例外

  

由于:java.nio.file.FileSystemException:   / mnt / s3 / emrfs-2408623010549537848 / 0000000000:在打开的文件太多   sun.nio.fs.UnixException.translateToIOException(UnixException.java:91)     在   sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:102)     在   sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:107)     在   sun.nio.fs.UnixFileSystemProvider.newByteChannel(UnixFileSystemProvider.java:214)     在java.nio.file.Files.newByteChannel(Files.java:361)在   java.nio.file.Files.createFile(Files.java:632)在   com.amazon.ws.emr.hadoop.fs.files.TemporaryFiles.create(TemporaryFiles.java:70)     在   com.amazon.ws.emr.hadoop.fs.s3n.MultipartUploadOutputStream.openNewPart(MultipartUploadOutputStream.java:493)     ...还有21

     

ApplicationMaster主机:10.97.57.1​​98 ApplicationMaster RPC端口:0      队列:默认开始时间:1542344243252最终状态:失败
  跟踪网址:   http://ip-10-97-57-234.tr-fr-nonprod.aws-int.thomsonreuters.com:20888/proxy/application_1542343091900_0001/      用户:线程“ main”中的hadoop异常   org.apache.spark.SparkException:应用程序   application_1542343091900_0001完成,状态为失败

还有

  

com.amazon.ws.emr.hadoop.fs.shaded.com.amazonaws.services.s3.model.AmazonS3Exception:   请降低您的请求率。 (服务:Amazon S3;状态代码:   503;错误代码:SlowDown;申请编号:D33581CA9A799F64; S3扩展   要求编号:   / SlEplo + lCKQRVVH + zHiop0oh8q8WqwnNykK3Ga6 / VM2HENl / eKizbd1rg4vZD1BZIpp8lk6zwA =),   S3扩展请求ID:   / SlEplo + lCKQRVVH + zHiop0oh8q8WqwnNykK3Ga6 / VM2HENl / eKizbd1rg4vZD1BZIpp8lk6zwA =

这是我的代码。

object TestAudit {

  def main(args: Array[String]) {


    val inputPath = args(0)
    val output = args(1)
    val noOfHashPartitioner = args(2).toInt

    //val conf = new SparkConf().setAppName("AuditXML").setMaster("local");
    val conf = new SparkConf().setAppName("AuditXML")

    val sc = new SparkContext(conf);
    val input = sc.textFile(inputPath)


    val pairedRDD = input.map(row => {
      val split = row.split("\\|")
      val fileName = split(0)
      val fileContent = split(1)
      (fileName, fileContent)
    })

    import org.apache.hadoop.io.NullWritable
    import org.apache.spark.HashPartitioner
    import org.apache.hadoop.mapred.lib.MultipleTextOutputFormat

    class RddMultiTextOutputFormat extends MultipleTextOutputFormat[Any, Any] {
      override def generateActualKey(key: Any, value: Any): Any = NullWritable.get()
      override def generateFileNameForKeyValue(key: Any, value: Any, name: String): String = key.asInstanceOf[String]
    }

    pairedRDD.partitionBy(new HashPartitioner(10000)).saveAsHadoopFile("s3://a205381-tr-fr-development-us-east-1-trf-auditabilty//AUDITOUTPUT", classOf[String], classOf[String], classOf[RddMultiTextOutputFormat], classOf[GzipCodec])

  }

}

即使我尝试不减少任何HashPartitioner,它也不起作用

1 个答案:

答案 0 :(得分:0)

Unix系统上的每个进程都有打开文件或文件描述符数量的限制。由于您的数据很大,并且分区到子文件(在Spark内部),因此您的过程遇到了限制和错误。 您可以为每个用户增加文件描述符的数量,如下所示:

编辑文件: /etc/security/limits.conf 并添加(或修改)

*         hard    nofile      500000
*         soft    nofile      500000
root      hard    nofile      500000
root      soft    nofile      500000

这会将每个用户和root用户的 nofile (文件描述符数量)功能设置为 500000

重新启动后,更改将被应用。

另外,有人可以通过设置 LimitNOFILE 来设置特殊进程的文件描述符数量。例如,如果使用yarn来运行Spark作业,而Yarn守护程序将使用 systemd 启动,则可以将LimitNOFILE = 128000添加到Yarn systemd脚本(资源管理器和nodemanager)中,以设置Yarn进程号。 128000 的文件描述符。

相关文章: