VM 記憶體不足錯誤的疑難排解

本頁說明 Dataproc on Compute Engine VM 發生記憶體不足 (OOM) 錯誤的狀況,並說明如何排解及解決 OOM 錯誤。

OOM 錯誤的影響

當 Dataproc on Compute Engine VM 發生記憶體不足 (OOM) 錯誤時,會出現下列情況:

  • 主要執行個體和 worker VM 會凍結一段時間。

  • 主要執行個體 VM 的 OOM 錯誤會導致工作失敗,並顯示「task not acquired」(未獲取任務) 錯誤。

  • Worker VM 發生記憶體不足錯誤,會導致 YARN HDFS 上的節點遺失,進而延遲 Dataproc 工作執行作業。

YARN 記憶體控制選項

Apache YARN 提供下列類型的記憶體控制選項

  • 輪詢式 (舊版)
  • 嚴格
  • 彈性

根據預設,Dataproc 不會設定 yarn.nodemanager.resource.memory.enabled 來啟用 YARN 記憶體控制選項,原因如下:

  • 在嚴格記憶體控制模式下,如果容器大小設定有誤,即使記憶體充足也可能終止容器。
  • 彈性記憶體控制模式的需求條件,可能會對工作執行效能造成負面影響。
  • 如果程序大量消耗記憶體,YARN 記憶體控制選項可能無法防止 OOM 錯誤。

Dataproc 記憶體保護

如果 Dataproc 叢集 VM 的記憶體不足,Dataproc 記憶體保護機制會終止程序或容器,直到記憶體不足的狀況解除為止。

Dataproc 會為下列叢集節點提供記憶體保護機制,適用於以下 Dataproc on Compute Engine 映像檔版本

角色 1.5 2.0 2.1 2.2
主要執行個體 VM 1.5.74+ 2.0.48+ 全部 全部
Worker VM 不適用 2.0.76+ 2.1.24+ 全部
驅動程式集區 VM 不適用 2.0.76+ 2.1.24+ 全部

識別並確認記憶體保護機制所觸發的終止事件

以下資訊可用於識別並確認工作是否因記憶體壓力而終止。

程序終止

  • 由 Dataproc 記憶體保護機制所終止的程序,會以 137143 程式碼結束。

  • 如果 Dataproc 因記憶體壓力而終止程序,可能會發生下列動作或情況:

    • Dataproc 會遞增累計指標,並將 reason 設為 ProcessKilledDueToMemoryPressuredataproc.googleapis.com/node/problem_count請參閱「收集 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 code」。如要查看這些訊息,請啟用 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 提高至實際的工作記憶體用量。
    • 如果叢集沒有驅動程式集區,請重新建立叢集,並降低叢集上執行的並行工作數量上限
    • 使用記憶體增量的主要節點機型。

Worker 節點 YARN 容器終止

  • Dataproc 會在 YARN Resource Manager 中寫入以下訊息: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 容器所能分配到的記憶體用量。
    • 如果工作容器持續執行失敗,請檢查是否因資料偏斜而導致特定容器用量增加。若是如此,請重新分割工作或增加 worker大 小,以因應額外的記憶體需求。

在主要節點上微調 Linux 記憶體保護功能 (進階)

在可用記憶體嚴重不足時,Dataproc 主要節點會使用 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 65536,也就是 64 MiB

    如果主要節點的記憶體容量較大,請調高這個值。例如,若要將閾值設為 1 GiB (1048576 KiB),請如下修改該行:

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

    附註:

    • -r:記憶體報告間隔 (以秒為單位)
    • -s:觸發 earlyoom 的交換空間閾值
  4. 重新啟動 earlyoom 服務,以套用變更:

    sudo systemctl restart earlyoom