VM のメモリ不足エラーのトラブルシューティング

目的: このページでは、Compute Engine VM 上の Managed Service for Apache Spark のメモリ不足(OOM)エラーに関する情報と、トラブルシューティングおよび OOM エラーを解決するために実行可能な手順について説明します。

OOM エラーの影響

Managed Service for Apache Spark VM でメモリ不足(OOM)エラーが発生すると、次のような影響が生じます。

  • マスター VM とワーカー VM が一時的にフリーズする。

  • マスター VM の OOM エラーにより、ジョブが「タスクが取得されませんでした」というエラーで失敗する。

  • ワーカー VM の OOM エラーにより、YARN HDFS でノードが失われ、Managed Service for Apache Spark ジョブの実行が遅延する。

YARN メモリ制御

Apache YARN には、次のタイプのメモリ制御が用意されています。

  • ポーリング ベース(従来版)
  • Strict
  • Elastic

デフォルトでは、次の理由により、Managed Service for Apache Spark は YARN メモリ制御を有効にするように yarn.nodemanager.resource.memory.enabled を設定しません。

  • 厳格なメモリ制御では、コンテナのサイズが正しく構成されていない場合、メモリが十分にあるにもかかわらずコンテナが終了する可能性があります。
  • 弾力性のあるメモリ制御の要件は、ジョブの実行に悪影響を及ぼす可能性があります。
  • プロセスがメモリを積極的に消費している場合、YARN メモリ制御で OOM エラーを回避できなくなる可能性があります。

Managed Service for Apache Spark のメモリ保護

Managed Service for Apache Spark クラスタ VM でメモリ不足が発生すると、Managed Service for Apache Spark メモリ保護により、OOM 状態が解除されるまでプロセスまたはコンテナが終了します。

Managed Service for Apache Spark は、次のクラスタ ノードに、次の Managed Service for Apache Spark イメージ バージョンでメモリ保護を提供します。

ロール 1.5 2.0 2.1 2.2
マスター VM 1.5.74+ 2.0.48+ すべて すべて
ワーカー VM 利用不可 2.0.76+ 2.1.24+ すべて
ドライバプール VM 利用不可 2.0.76+ 2.1.24+ すべて

メモリ保護の終了を特定して確認する

次の情報を使用することで、メモリ圧力によるジョブの終了を特定して確認できます。

プロセスの終了

  • Managed Service for Apache Spark のメモリ保護によって終了するプロセスは、コード 137 または 143 で終了します。

  • Managed Service for Apache Spark がメモリ負荷のためにプロセスを終了すると、次のアクションまたは状態が発生する可能性があります。

    • Managed Service for Apache Spark は、dataproc.googleapis.com/node/problem_count 累積指標を増やし、reasonProcessKilledDueToMemoryPressure に設定します。 Managed Service for Apache Spark リソース指標の収集をご覧ください。
    • Managed Service for Apache Spark は、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:"
      

マスターノードまたはドライバ ノードプールのジョブの終了

  • メモリ負荷が原因で Managed Service for Apache Spark マスターノードまたはドライバ ノードプールのジョブ が終了すると、ジョブはエラー 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 を確認して、Managed Service for Apache Spark メモリ保護が ジョブを終了したことを確認します(プロセスの終了をご覧ください)。

    解決策:

    • クラスタにドライバプールがある場合は、driver-required-memory-mb を実際のジョブメモリ使用量に増やします。
    • クラスタにドライバプールがない場合は、クラスタを再作成して、クラスタで実行される同時実行ジョブの最大数を減らします。
    • メモリ容量を増やしてマスターノード マシンタイプを使用します。

ワーカーノードの YARN コンテナの終了

  • Managed Service for Apache Spark は 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 を確認して、Managed Service for Apache Spark メモリ保護がジョブを終了したことを確認します (プロセスの終了をご覧ください)。

    解決策:

    • コンテナのサイズが正しく構成されていることを確認します。
    • yarn.nodemanager.resource.memory-mb を下げることを検討してください。このプロパティは、YARN コンテナのスケジューリングに使用されるメモリ量を制御します。
    • ジョブコンテナが常に失敗する場合は、データスキューが特定のコンテナの使用量の増加を引き起こしているかどうかを確認します。その場合は、ジョブを再パーティショニングするか、ワーカーのサイズを増やして、追加のメモリ要件に対応します。

マスターノードで Linux のメモリ保護を微調整する(高度な設定)

Managed Service for Apache Spark マスターノードは、使用可能なメモリが非常に少ない場合にメモリを解放することで、earlyoom ユーティリティを使用してシステムハングを防ぎます。デフォルト構成は、多くのワークロードに適しています。ただし、マスターノードに大量のメモリがあり、メモリ消費が急速に増加する場合は、構成の調整が必要になることがあります。

メモリ不足が深刻なシナリオでは、システムが「スラッシング」状態になることがあります。この状態では、システムがメモリ管理にほとんどの時間を費やし、応答しなくなります。この処理は非常に迅速に行われるため、earlyoom がデフォルト設定に基づいてアクションを実行できない可能性や、カーネル OOM 応答が呼び出される前にアクションを実行できない可能性があります。

始める前に

  • これは高度なチューニング オプションです。earlyoom 設定を調整する前に、メモリ容量が大きいマスター VM の使用、ジョブの同時実行数の削減、ジョブのメモリ使用量の最適化など、他の解決策を優先します。

earlyoom 設定をカスタマイズする

デフォルトの earlyoom 構成では、固定量の空きメモリがトリガーとして使用されます。大量の RAM を搭載した(32GB 以上など)仮想マシンでは、この固定量が合計メモリのほんの一部である可能性があります。これにより、システムはメモリ使用量の急激な増加の影響を受けやすくなります。

earlyoom 設定をカスタマイズするには、マスターノードに接続して構成ファイルを変更します。

  1. SSH を使用してマスターノードに接続します

  2. 構成ファイルを編集用に開きます。

    sudo nano /etc/default/earlyoom
    
  3. 最小メモリしきい値を調整します。EARLYOOM_ARGS 行を見つけます。-M <kbytes> オプションは、earlyoom が維持しようとする空きメモリの最小量を KiB 単位で設定します。デフォルト値は -M 6553664 MiB)です。

    メモリ容量が大きいマスターノードの場合は、この値を大きくします。たとえば、しきい値を 1 GiB1048576 KiB)に設定するには、次のように行を変更します。

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

    注:

    • -r: メモリレポートの間隔(秒単位)
    • -s: earlyoom をトリガーするスワップ領域のしきい値
  4. earlyoom サービスを再起動して変更を適用します。

    sudo systemctl restart earlyoom