调试 Hadoop reducer OutOfMemoryError

Debugging Hadoop reducer OutOfMemoryError

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

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

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

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

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

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

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