【问题标题】:Debugging Hadoop reducer OutOfMemoryError调试 Hadoop 减速器 OutOfMemoryError
【发布时间】:2021-02-13 05:40:16
【问题描述】:

我正在尝试调试 OutOfMemoryError 我正在使用我的 Hadoop 减速器。映射器成功完成。它们生成小于 128 字节的小记录。在我的 reducer 中,我使用相同的键(大约有 15 个可能的键)收集记录,然后用MultipleOutputs 将它们写入单独的输出文件。每个键的记录分布不均匀。

在减少阶段的中间,我开始收到OutOfMemoryErrors。我检查了很多东西:

  • reducer 不保存数据;一旦它得到一个值,它就会把它写到相应的输出中
  • 我为减少任务的数量尝试了不同的值。在我的情况下调整这个有点奇怪,因为超过 15 个键没有帮助,因为只有 15 个键
  • 实例化MultipleOutputs 并在reduce() 中关闭它,认为它保留了输出文件的资源。这只是因为键和输出文件具有一对一的映射关系。
  • 我尝试将数据添加到键的末尾,以便数据在 reduce 任务之间均匀分布
  • 出于偏执,mapreduce.reduce.shuffle.memory.limit.percent=0
  • 经过验证的键和值确实很小
  • 禁用输出压缩,认为压缩器中存在内存泄漏
  • 盲目地调整mapreduce.reduce.shuffle.merge.percent之类的东西

除了积极缓冲 shuffle 输出之外,我不确定内存还能去哪里。

这是在带有 Hadoop 3.2.2 的 GCP Dataproc 上运行的。很多指南推荐设置mapreduce.reduce.java.opts。我试过这个没有成功,但我也假设谷歌为主机大小选择了一个合理的默认值,而且我没有关于内存去向的令人信服的故事。我的另一个理论是GoogleHadoopOutputStream 中写入云存储的东西正在缓冲。我有一些 10GB 到 100GB 的输出文件——比机器的内存还大。

我还应该看什么?我应该尝试调整这些其他标志吗?附加 VisualVM 看起来并不容易,但堆转储会有所帮助吗?

【问题讨论】:

    标签: hadoop google-cloud-platform memory-leaks google-cloud-dataproc


    【解决方案1】:

    每个GoogleHadoopOutputStream 消耗大约 70 MiB 的 JVM 堆,因为它默认以 64 MiB 的块将数据上传到 Google Cloud Storage。这就是为什么如果你在同一个 MR 任务中使用 MultipleOutputs 编写多个对象,每个任务都需要 number of outputs x 70 MiB JVM 堆。

    您可以通过 fs.gs.outputstream.upload.chunk.size property 减少每个 GoogleHadoopOutputStream 消耗的内存,但这也会降低上传到 Google Cloud Storage 的速度,这就是为什么更好的方法是重构您的 MR 作业以编写单个/更少的文件在每个 MR 任务中。

    【讨论】:

    • 我检查了一个堆转储,你成功了。我还会考虑为每个任务编写更少的文件。
    猜你喜欢
    • 2015-01-11
    • 1970-01-01
    • 2014-05-21
    • 2016-07-02
    • 2016-08-13
    • 1970-01-01
    • 1970-01-01
    • 2018-03-09
    • 2010-10-24
    相关资源
    最近更新 更多