工作失敗“沒有足夠的內存來構建哈希映射”錯誤

您應該使用自適應查詢執行而不是顯式的廣播提示上麵的磚運行時11.3 LTS和執行連接。

寫的saritha.shivakumar

去年發表在:2023年5月12日
刪除

信息

本文適用於磚運行時11.3 LTS及以上。


問題

您正在運行SparkSQL / PySpark代碼使用廣播提示。需要花費很長的時間來運行比以前磚運行時和/或失敗的記憶錯誤消息。

示例代碼:

df.join(廣播(bigDf) .write.mode .parquet(“覆蓋”)(“路徑”)

錯誤信息:

工作階段失敗而終止:沒有足夠的內存來構建造成的散列映射:沒有足夠的內存來構建散列映射


如果你檢查SQL選項卡下的執行計劃在Apache火花UI,它表示失敗發生在一個執行人廣播加入。

導致

遺囑執行人一邊播放加入(ejb)是一種增強了運行時11.3 LTS磚。它優化廣播的方式加入功能。以前,廣播連接依賴的火花司機廣播的一方加入。雖然這種方法有效,它提出了以下挑戰:

  • 單點故障:司機,集群中的所有查詢的協調員,麵臨失敗的風險增加,由於JVM的內存錯誤當用於廣播所有並發查詢。在這種情況下,所有查詢同時運行在集群上可能會受到影響和潛在的失敗。
  • 有限的靈活性增加默認播放加入閾值:內存不足錯誤司機的風險(由於並發廣播)很難增加默認播放加入閾值(目前10 mb 30 mb的靜態和動態),因為這將添加更多的內存壓力驅動程序和提升失敗的風險。


EBJ增強解決這些挑戰,把內存壓力從司機的執行人。這不僅消除了單點故障,還允許增加默認播放加入門檻,由於總集群失敗的風險降低。

啟用了EBJ,不幸的是,查詢,使用顯式廣播提示現在可能失敗。這是更有可能與一個更大的數據集。

遇到的問題是相關的內存消耗在駕駛員一側廣播管理。使用的內存駕駛員一側廣播控製spark.driver.maxResultSize。在早期版本中,用於廣播的內存中沒有顯式跟蹤和占內存管理器的任務。這意味著這個任務可能低估了內存使用。因此,較大的作業可能看似隨機失敗,由於內存不足錯誤,而另一些人會成功是因為運氣。

啟用了EBJ,為廣播散列映射分配的內存是準確地跟蹤和扣除任務的內存管理器的可用內存。這個改進降低了內存泄漏的風險和JVM的內存錯誤。因此,大型廣播可能以不同的方式處理,而且還提高了可靠性。

解決方案

跟蹤內存使用ejb是至關重要的防止JVM的內存錯誤,從而導致所有並發查詢節點的失敗。

而不是使用廣播提示,你應該讓自適應查詢執行(AWS|Azure|GCP)選擇加入適用於工作量根據所處理的數據的大小。

這篇文章有用嗎?