【问题标题】:Reducer's Heap out of memory减速器堆内存不足
【发布时间】:2012-01-02 22:20:45
【问题描述】:

所以我有一些 Pig 脚本在那里不断死去,减少了作业的阶段,错误是 Java 堆不断耗尽空间。到目前为止,我唯一的解决方案是增加 Reducer 的数量,但这似乎并没有让我有任何可靠的地方。现在,其中一部分可能只是我们获得的数据的大量增长,但不能确定。

我考虑过更改溢出阈值设置,但不记得该设置,但不确定它们是否会有所帮助或只是减慢速度。我还可以采取哪些其他措施来解决此问题?

附带说明一下,当这种情况开始发生时,我也会收到关于 bash 未能获取内存的错误,我认为这是溢出操作。这会是 Hadoop 节点内存不足吗?如果是这样,只是降低这些盒子上的堆大小是解决方案吗?

编辑 1
1) 猪 0.8.1
2) 唯一的 UDF 是一个 eval udf,它只查看没有包或地图的单行。
3)我没有注意到有任何热点分布不良。我也一直在使用素数比例来减少这个问题。

编辑 2
这是有问题的错误:
2012-01-04 09:58:11,179 FATAL org.apache.hadoop.mapred.TaskRunner: attempt_201112070707_75699_r_000054_1 : Map output copy failure : java.lang.OutOfMemoryError: Java heap space at org.apache.hadoop.mapred.ReduceTask$ReduceCopier$MapOutputCopier.shuffleInMemory(ReduceTask.java:1508) at org.apache.hadoop.mapred.ReduceTask$ReduceCopier$MapOutputCopier.getMapOutput(ReduceTask.java:1408) at org.apache.hadoop.mapred.ReduceTask$ReduceCopier$MapOutputCopier.copyOutput(ReduceTask.java:1261) at org.apache.hadoop.mapred.ReduceTask$ReduceCopier$MapOutputCopier.run(ReduceTask.java:1195)

这是我不断收到的 bash 错误:
java.io.IOException: Task: attempt_201112070707_75699_r_000054_0 - The reduce copier failed at org.apache.hadoop.mapred.ReduceTask.run(ReduceTask.java:380) at org.apache.hadoop.mapred.Child.main(Child.java:170) Caused by: java.io.IOException: Cannot run program "bash": java.io.IOException: error=12, Cannot allocate memory at java.lang.ProcessBuilder.start(ProcessBuilder.java:460) at org.apache.hadoop.util.Shell.runCommand(Shell.java:149) at org.apache.hadoop.util.Shell.run(Shell.java:134) at org.apache.hadoop.fs.DF.getAvailable(DF.java:73) at org.apache.hadoop.fs.LocalDirAllocator$AllocatorPerContext.getLocalPathForWrite(LocalDirAllocator.java:329) at org.apache.hadoop.fs.LocalDirAllocator.getLocalPathForWrite(LocalDirAllocator.java:124) at org.apache.hadoop.mapred.MapOutputFile.getInputFileForWrite(MapOutputFile.java:160) at org.apache.hadoop.mapred.ReduceTask$ReduceCopier$InMemFSMergeThread.doInMemMerge(ReduceTask.java:2537) at org.apache.hadoop.mapred.ReduceTask$ReduceCopier$InMemFSMergeThread.run(ReduceTask.java:2501)

【问题讨论】:

  • 因此,经过进一步研究,我发现了一个部分解决方法,这似乎有助于解决问题,还有一些错误报告称该问题的某些变体已在 Hadoop 0.20.2 中得到解决。解决方法是将以下行添加到您的 pig 脚本或将其添加到您的 pig.properties 文件中。默认值为 0.70 或 70%。 "设置 mapred.job.shuffle.input.buffer.percent 0.50;"

标签: hadoop mapreduce apache-pig


【解决方案1】:

显然,您的某个地方内存不足。增加reducer的数量其实是相当合理的。查看 JobTracker Web GUI 上的统计信息,看看有多少字节从映射器中流出。将其除以reduce 任务的数量,这是对每个reducer 得到的相当粗略的估计。不幸的是,从长远来看,这只有在您的密钥分布均匀时才有效。

在某些情况下,JOIN(尤其是复制类型)会导致此类问题。当您拥有特定键的“热点”时,就会发生这种情况。例如,假设您正在执行某种连接,并且其中一个键出现 50% 的时间。无论 reducer 幸运地处理了该密钥,都会遭到破坏。您可能需要调查哪些键导致热点并相应地处理它们。在我的数据中,通常这些热点无论如何都是无用的。要找出热门内容,只需执行GROUP BYCOUNT 并找出最热门的内容。然后,如果它没有用,就直接FILTER 吧。

此问题的另一个来源是 Java UDF 聚合了太多数据。例如,如果您有一个 UDF,它通过数据包并将记录收集到某种列表数据结构中,您可能会因为热点值而记忆犹新。

我发现新版本的 Pig(尤其是 .8 和 .9)的内存问题要少得多。我在 0.7 中有很多堆用完的实例。这些版本具有更好的溢出到磁盘检测功能,因此如果它即将破坏堆,它足够智能以溢出到磁盘。


为了让我更有帮助,您可以发布您的 Pig 脚本,并说明您使用的是什么版本的 Pig。

【讨论】:

  • 我在原始问题中添加了您询问的详细信息
【解决方案2】:

我不是经验丰富的用户或任何人,但在 VM 上运行猪作业时确实遇到了类似的问题。

我的特殊问题是虚拟机没有配置交换空间,它最终会耗尽内存。我猜您是在正确的 linux 配置中尝试此操作,但执行以下操作不会有什么坏处:free -m 并查看您得到的结果,可能问题是由于您配置的交换内存太少。

只是一个想法,如果有帮助,请告诉我。祝你好运!

【讨论】:

  • 我们实际上关闭了swappiness。即甚至不允许使用交换。但是在听了 Hadoop 的一位创始人的演讲之后。在更高版本的 Hadoop(0.23、1.0)中添加了一个新配置,可以帮助您解决这个问题。似乎当袋子溢出时,它会产生一个大小相同的孩子。现在要处理这个问题,您需要将您的作品数量配置为可用资源的一半。新配置允许您现在控制父进程和子进程的所有内存。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-09-10
  • 2021-07-05
  • 2018-02-10
  • 2013-08-09
  • 2017-09-09
相关资源
最近更新 更多