Java 当输入文件数较大时,超出了Map Reduce的GC开销限制

Java 当输入文件数较大时,超出了Map Reduce的GC开销限制,java,mapreduce,hadoop2,Java,Mapreduce,Hadoop2,我已经写了MR作业,它将处理5800多个输入文件。 当我启动它时,它失败了,“线程中的异常”main“java.lang.OutOfMemoryError:超出了GC开销限制”。 以下是异常堆栈跟踪: Exception in thread "main" java.lang.OutOfMemoryError: GC overhead limit exceeded at org.apache.hadoop.security.token.Token.<init>(Token.ja

我已经写了MR作业,它将处理5800多个输入文件。 当我启动它时,它失败了,“线程中的异常”main“java.lang.OutOfMemoryError:超出了GC开销限制”。 以下是异常堆栈跟踪:

Exception in thread "main" java.lang.OutOfMemoryError: GC overhead limit exceeded
    at org.apache.hadoop.security.token.Token.<init>(Token.java:85)
    at org.apache.hadoop.hdfs.protocol.LocatedBlock.<init>(LocatedBlock.java:52)
    at org.apache.hadoop.hdfs.protocolPB.PBHelper.convert(PBHelper.java:755)
    at org.apache.hadoop.hdfs.protocolPB.PBHelper.convertLocatedBlock(PBHelper.java:1174)
    at org.apache.hadoop.hdfs.protocolPB.PBHelper.convert(PBHelper.java:1192)
    at org.apache.hadoop.hdfs.protocolPB.PBHelper.convert(PBHelper.java:1328)
    at org.apache.hadoop.hdfs.protocolPB.PBHelper.convert(PBHelper.java:1436)
    at org.apache.hadoop.hdfs.protocolPB.PBHelper.convert(PBHelper.java:1445)
    at org.apache.hadoop.hdfs.protocolPB.ClientNamenodeProtocolTranslatorPB.getListing(ClientNamenodeProtocolTranslatorPB.java:549)
    at sun.reflect.GeneratedMethodAccessor4.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.apache.hadoop.io.retry.RetryInvocationHandler.invokeMethod(RetryInvocationHandler.java:187)
    at org.apache.hadoop.io.retry.RetryInvocationHandler.invoke(RetryInvocationHandler.java:102)
    at com.sun.proxy.$Proxy23.getListing(Unknown Source)
    at org.apache.hadoop.hdfs.DFSClient.listPaths(DFSClient.java:1893)
    at org.apache.hadoop.hdfs.DistributedFileSystem$15.<init>(DistributedFileSystem.java:742)
    at org.apache.hadoop.hdfs.DistributedFileSystem.listLocatedStatus(DistributedFileSystem.java:731)
    at org.apache.hadoop.fs.FileSystem.listLocatedStatus(FileSystem.java:1664)
    at org.apache.hadoop.mapreduce.lib.input.FileInputFormat.singleThreadedListStatus(FileInputFormat.java:300)
    at org.apache.hadoop.mapreduce.lib.input.FileInputFormat.listStatus(FileInputFormat.java:264)
    at org.apache.hadoop.mapreduce.lib.input.SequenceFileInputFormat.listStatus(SequenceFileInputFormat.java:59)
    at org.apache.hadoop.mapreduce.lib.input.FileInputFormat.getSplits(FileInputFormat.java:385)
    at org.apache.hadoop.mapreduce.JobSubmitter.writeNewSplits(JobSubmitter.java:589)
    at org.apache.hadoop.mapreduce.JobSubmitter.writeSplits(JobSubmitter.java:606)
    at org.apache.hadoop.mapreduce.JobSubmitter.submitJobInternal(JobSubmitter.java:490)
    at org.apache.hadoop.mapreduce.Job$10.run(Job.java:1295)
    at org.apache.hadoop.mapreduce.Job$10.run(Job.java:1292)
    at java.security.AccessController.doPrivileged(Native Method)
    at javax.security.auth.Subject.doAs(Subject.java:415)
    at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1642)
    at org.apache.hadoop.mapreduce.Job.submit(Job.java:1292)
线程“main”java.lang.OutOfMemoryError中出现异常:超出GC开销限制 位于org.apache.hadoop.security.token.token.(token.java:85) 位于org.apache.hadoop.hdfs.protocol.LocatedBlock.(LocatedBlock.java:52) 位于org.apache.hadoop.hdfs.protocolPB.PBHelper.convert(PBHelper.java:755) 位于org.apache.hadoop.hdfs.protocolPB.PBHelper.convertLocatedBlock(PBHelper.java:1174) 位于org.apache.hadoop.hdfs.protocolPB.PBHelper.convert(PBHelper.java:1192) 位于org.apache.hadoop.hdfs.protocolPB.PBHelper.convert(PBHelper.java:1328) 位于org.apache.hadoop.hdfs.protocolPB.PBHelper.convert(PBHelper.java:1436) 位于org.apache.hadoop.hdfs.protocolPB.PBHelper.convert(PBHelper.java:1445) 位于org.apache.hadoop.hdfs.protocolPB.ClientNamenodeProtocolTranslatorPB.getListing(ClientNamenodeProtocolTranslatorPB.java:549) 位于sun.reflect.GeneratedMethodAccessor4.invoke(未知源) 在sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)中 位于java.lang.reflect.Method.invoke(Method.java:606) 位于org.apache.hadoop.io.retry.RetryInvocationHandler.invokeMethod(RetryInvocationHandler.java:187) 位于org.apache.hadoop.io.retry.RetryInvocationHandler.invoke(RetryInvocationHandler.java:102) 位于com.sun.proxy.$Proxy23.getListing(未知源) 位于org.apache.hadoop.hdfs.DFSClient.listPaths(DFSClient.java:1893) 位于org.apache.hadoop.hdfs.DistributedFileSystem$15。(DistributedFileSystem.java:742) 位于org.apache.hadoop.hdfs.DistributedFileSystem.listLocatedStatus(DistributedFileSystem.java:731) 位于org.apache.hadoop.fs.FileSystem.listLocatedStatus(FileSystem.java:1664) 位于org.apache.hadoop.mapreduce.lib.input.FileInputFormat.singleThreadedListStatus(FileInputFormat.java:300) 位于org.apache.hadoop.mapreduce.lib.input.FileInputFormat.listStatus(FileInputFormat.java:264) 位于org.apache.hadoop.mapreduce.lib.input.SequenceFileInputFormat.listStatus(SequenceFileInputFormat.java:59) 位于org.apache.hadoop.mapreduce.lib.input.FileInputFormat.getSplits(FileInputFormat.java:385) 在org.apache.hadoop.mapreduce.jobsmitter.writeNewSplits(jobsmitter.java:589)上 位于org.apache.hadoop.mapreduce.jobsmitter.writeSplits(jobsmitter.java:606) 位于org.apache.hadoop.mapreduce.jobsmitter.submitJobInternal(jobsmitter.java:490) 位于org.apache.hadoop.mapreduce.Job$10.run(Job.java:1295) 位于org.apache.hadoop.mapreduce.Job$10.run(Job.java:1292) 位于java.security.AccessController.doPrivileged(本机方法) 位于javax.security.auth.Subject.doAs(Subject.java:415) 位于org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1642) 位于org.apache.hadoop.mapreduce.Job.submit(Job.java:1292) Map Reduce的输入文件数量是否有限制。
我尝试使用1.2GB的alos内存运行它,因为您没有向我们展示任何代码,所以只能泛泛地讨论

这个问题不是由Hadoop对文件数量的任何特定限制引起的。这可能是由于文件的总大小。。。在它们的内容被读取并加载到堆中之后。但不一定

这里实际发生的情况是,您已经(几乎)填满了堆,JVM决定您花费了太多的时间来收集垃圾

一般来说,这类问题有三个可能的原因:

  • 堆对于您试图解决的问题的大小来说太小了
  • 您的应用程序内存使用效率低下
  • 您的应用程序存在内存泄漏
  • 在你的情况下,我首先假设这是问题1。我会尝试使用更少的文件和/或尝试使用更大的堆。如果这两种方法中的任何一种都能解决问题,那么你就完成了(现在),尽管这显然会限制你能处理的问题的大小

    如果这不能解决问题,那么您将把它当作是在寻找内存泄漏;i、 e.找出应用程序使用如此多(太多)内存的原因


    我要指出的是,1.2Gb并不是一个特别大的堆。

    从stacktrace判断,我可以提供一些帮助,问题确实出在文件列表上。对于拥有太多小文件的MapReduce作业和使用Java默认堆大小从笔记本电脑开始大作业的开发人员来说,这是一个常见的问题。@ThomasJungblut-我们不能得出这样的结论。我们唯一可以安全得出的结论是,问题(GC开销限制)是在列出文件时检测到的。事实上OP告诉我们有5800个输入文件。。。这往往表明列出文件不是问题所在。现在。。。也许OP是错的。但是我们没有明确的证据。对不起,我不能分享代码,因为它是银行的项目代码库。作业初始化类(已配置和工具类的子类),它获取CSV文件中的输入路径,并对其进行迭代并调用FileInputFormat.addInputPath(作业,新路径(inputPath));对于所有提供的路径。我试过了,就像我说的。如果你不给我们看代码,我/我们只能泛泛而谈。当然,如果你真的需要帮助,你可以构建一个MCVE来演示这个问题。。。删除/替换所有敏感代码。@StephenC我知道这些是5.8k目录(这是
    getListing
    提供给您的)。这些文件可能会更多,因此5.8k是乘数而不是实际数字。您在哪里增加了内存?OOM发生在提交时,因此客户端应用程序需要更多堆。我不知道为什么人们会反对它