【发布时间】: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