排查虚拟机内存不足错误

本页面介绍了 Dataproc on Compute Engine 虚拟机内存不足 (OOM) 错误,并说明了您可以采用哪些步骤来排查和解决 OOM 错误。

OOM 错误的影响

当 Dataproc on Compute Engine 虚拟机遇到内存不足 (OOM) 错误时,产生的影响包括以下条件:

  • 主虚拟机和工作器虚拟机冻结一段时间。

  • 主虚拟机 OOM 错误会导致作业失败,并显示“未获取任务”错误。

  • 工作器虚拟机 OOM 错误会导致 YARN HDFS 上的节点丢失,从而延迟 Dataproc 作业执行。

YARN 内存控制

Apache YARN 提供以下类型的内存控制

  • 基于轮询(旧版)
  • 严格
  • Elastic

默认情况下,Dataproc 不会设置 yarn.nodemanager.resource.memory.enabled 来启用 YARN 内存控制,原因如下:

  • 如果容器大小配置不正确,严格的内存控制可能会导致在内存充足的情况下终止容器。
  • 弹性内存控制要求可能会对作业执行产生不利影响。
  • 当进程大量消耗内存时,YARN 内存控制可能无法防止 OOM 错误。

Dataproc 内存保护

当 Dataproc 集群虚拟机面临内存压力时,Dataproc 内存保护会终止进程或容器,直到 OOM 条件消除为止。

Dataproc 在以下 Dataproc on Compute Engine 映像版本中为以下集群节点提供内存保护:

角色 1.5 2.0 2.1 2.2
主虚拟机 1.5.74+ 2.0.48+ 全部 全部
工作器虚拟机 不可用 2.0.76+ 2.1.24+ 全部
驱动程序池虚拟机 不可用 2.0.76+ 2.1.24+ 全部

识别并确认内存保护终止

您可以使用以下信息来识别和确认因内存压力而导致的作业终止。

进程终止

  • Dataproc 内存保护终止的进程退出并显示代码 137143

  • 当 Dataproc 因内存压力而终止进程时,可能会发生以下操作或情况:

    • Dataproc 会递增 dataproc.googleapis.com/node/problem_count 累计指标,并将 reason 设置为 ProcessKilledDueToMemoryPressure。请参阅 Dataproc 资源指标收集
    • Dataproc 会写入包含以下消息的 google.dataproc.oom-killer 日志:"A process is killed due to memory pressure: process name。如需查看这些消息,请启用 Logging,然后使用以下日志过滤条件:
      resource.type="cloud_dataproc_cluster"
      resource.labels.cluster_name="CLUSTER_NAME"
      resource.labels.cluster_uuid="CLUSTER_UUID"
      jsonPayload.message:"A process is killed due to memory pressure:"
      

主节点或驱动程序节点池作业终止

  • 当 Dataproc 主节点或驱动程序节点池作业因内存压力而终止时,作业会失败并显示错误 Driver received SIGTERM/SIGKILL signal and exited with INT 代码。如需查看这些消息,请启用 Logging,然后使用以下日志过滤条件:

    resource.type="cloud_dataproc_cluster"
    resource.labels.cluster_name="CLUSTER_NAME"
    resource.labels.cluster_uuid="CLUSTER_UUID"
    jsonPayload.message:"Driver received SIGTERM/SIGKILL signal and exited with"
        

    • 检查 google.dataproc.oom-killer 日志或 dataproc.googleapis.com/node/problem_count,以确认 Dataproc 内存保护是否终止了作业(请参阅进程终止)。

    解决方案

    • 如果集群具有驱动程序池,请将 driver-required-memory-mb 增加到实际作业内存用量。
    • 如果集群没有驱动程序池,请重新创建集群,并降低集群上运行的并发作业数上限
    • 使用具有更大内存的主节点机器类型。

工作器节点 YARN 容器终止

  • Dataproc 会在 YARN 资源管理器中写入以下消息:container id exited with code EXIT_CODE。如需查看这些消息,请启用 Logging,然后使用以下日志过滤条件:

    resource.type="cloud_dataproc_cluster"
    resource.labels.cluster_name="CLUSTER_NAME"
    resource.labels.cluster_uuid="CLUSTER_UUID"
    jsonPayload.message:"container" AND "exited with code" AND "which potentially signifies memory pressure on NODE
    
  • 如果容器以 code INT 退出,请检查 google.dataproc.oom-killer 日志或 dataproc.googleapis.com/node/problem_count 以确认 Dataproc 内存保护终止了作业(请参阅进程终止)。

    解决方案

    • 检查容器大小是否已正确配置。
    • 考虑降低 yarn.nodemanager.resource.memory-mb。此属性控制用于调度 YARN 容器的内存量。
    • 如果作业容器始终失败,请检查数据倾斜是否导致特定容器的用量增加。如果是,请对作业重新分区或增加工作器大小以满足额外的内存要求。

在主节点上微调 Linux 内存保护(高级)

Dataproc 主节点使用 earlyoom 实用程序,在可用内存严重不足时释放内存,以防止系统挂起。默认配置适用于许多工作负载。不过,如果主节点具有大量内存,但内存消耗速度很快,您可能需要调整配置。

在内存压力较大的情况下,系统可能会进入“抖动”状态,即大部分时间都用于内存管理,从而变为无响应。这种情况发生得非常快,以至于 earlyoom 无法根据其默认设置采取行动,或者无法在内核 OOM 响应被调用之前采取行动。

准备工作

  • 这是一项高级调优选项。在调整 earlyoom 设置之前,请优先考虑其他解决方案,例如使用具有更多内存的主虚拟机、减少作业并发数或优化作业内存用量。

自定义 earlyoom 设置

默认的 earlyoom 配置会使用固定量的可用内存作为触发条件。在具有大量 RAM(例如 32GB 或更多)的虚拟机上,此固定量可能仅占总内存的一小部分。这使得系统容易受到内存用量突然激增的影响。

如需自定义 earlyoom 设置,请连接到主节点并修改配置文件。

  1. 使用 SSH 连接到主节点

  2. 打开配置文件以进行修改:

    sudo nano /etc/default/earlyoom
    
  3. 调整最低内存阈值。找到 EARLYOOM_ARGS 行。-M <kbytes> 选项用于设置 earlyoom 尝试维持的最小可用内存量(以 KiB 为单位)。默认值为 -M 65536,即 64 MiB

    对于内存充足的主节点,你可以增加此值。例如,如需将阈值设置为 1 GiB1048576 KiB),请按如下方式修改相应行:

    EARLYOOM_ARGS="-r 15 -M 1048576 -s 1"
    

    注意:

    • -r:内存报告间隔时间(以秒为单位)
    • -s:触发 earlyoom 的交换空间阈值
  4. 重启 earlyoom 服务以应用更改:

    sudo systemctl restart earlyoom