Spark —— Spark OOM Error問題排查定位
文章目錄
Spark之所以能進行高效能的查詢計算,主要得益於其基於記憶體的計算模型,那麼在討論Spark 中的一系列OOM error之前,我們應該對Spark的記憶體模型有一個充分的瞭解(請參考: Spark記憶體模型),才能分析定位OOM出現的原因。Spark記憶體模型圖貼在這裡便於參考:
瞭解了Spark的記憶體模型之後,我們回到Spark OOM error上。當Spark應用程式因為OOM error中斷時,我們大概率會在報錯中看到諸如下面這樣的資訊:
java.lang.OutOfMemoryError: Java heap space
首先,我們要清楚的是根據Spark的執行架構可知,Spark OOM主要發生在兩個地方:Driver端和Executor端。
Driver端OOM Error
Driver端記憶體是通過配置“spark.driver.memory”來指定的,預設1g。注:在client模式下,此配置不能在應用程式中通過SparkConf設定,因為在SparkConf初始化之前,Driver JVM已經啟動了。這時,可以通過在spark-submit命令列指定–driver-memory來設定,或者配置到Spark的配置檔案(conf/spark_default.conf)中。
通常情況下,導致Driver端OOM的原因有以下兩種:
1. 不適合的API呼叫
比如,在大資料集(RDD/Dataset/DataFrame)上呼叫了collect()、collectAsList()、take()、takeAsList()等方法。這些方法會將所有要返回的資料從所有的Executor上傳送到Driver端,如果返回的資料超過了Driver記憶體,就會引發OOM Error。
針對這種情況,我們有以下3中解決方法:
- 最簡單粗暴的就是增加Driver端記憶體。
- 在RDD/Dataset上呼叫repartition()方法,將資料交給Executor上的一個任務處理。因為一般來講,Executor會設定較多的記憶體。
- 可以設定“spark.driver.maxResultSize”(預設1g)來避免Driver出現OOM errors。
2. 廣播了大變數
將RDD/Dataset進行廣播時,會先將它們傳送到Driver,然後由Driver端分發給每個Executor,如果我們的應用程式中廣播了多個大變數,超出了Driver記憶體限制,就可能造成OOM Error。
針對這種情況,我們有以下2中解決方法:
- 增加Driver端記憶體。
- 通過配置“spark.sql.autoBroadcastJoinThreshold”減小要廣播的變數的大小。
Executor端OOM Error
Executor端記憶體是通過配置“spark.executor.memory”來指定的,預設1g。
Executor端OOM Error原因:
1. 低效的查詢
比如,在列式儲存格式的表上執行select * from t返回不必要的列;沒有提前使用過濾條件過濾掉不必要的資料。
所以,我們在查詢的時候,要儘量將過濾條件前置;要儘量只讀需要的列;分割槽表上只查詢指定分割槽的資料等等。
2. 不合適的Driver端和Executor端記憶體
每個Spark應用程式所需的記憶體都是不一樣的,因此我們要結合所處理的資料的大小和應用監控(比如,Spark Web UI)來合理的為每個應用配置合適的Driver端和Executor端記憶體大小。
3. 不合適的YARN Container記憶體
當我們的Spark任務執行在YARN上的時候,可能會因為container記憶體負載造成OOM Error,出現類似如下的報錯:
......is running beyond physical memory limits. Current usage: xxxGB of xxxGB physical memory used; xxxGB of xxxGB virtual memory used. Killing container.....
這種情況我們需要給配置spark.yarn.executor.memoryOverhead(Spark 2.3.0之前)或spark.executor.memoryOverhead(Spark 2.3.0及之後)設定一個合適的值。此配置代表分配給每個Executor的非堆記憶體空間,這些記憶體空間主要用於VM開銷、interned strings以及其他本地開銷,預設值為executorMemory * 0.10,最小不能低於384MB。
4. 記憶體中快取大量資料
如果Spark應用程式指定在記憶體中快取了大的RDD/Dataset,或者是快取了較多的RDD/Dataset,就有可能發生OOM Error:
val df: Dataset[Row] = spark.read.table("")
df.persist(StorageLevel.MEMORY_ONLY) //Dataset全部快取到記憶體中
val rdd: RDD[Int] = ...
rdd.cache() //RDD全部快取到記憶體中
Spark記憶體模型中,Execution記憶體和Storage記憶體的總大小為0.6*(heap space - 300MB),這總大小裡面兩者預設各佔一半,我們應用中快取的哪些資料集正是儲存在Storage記憶體區域的。如果Spark應用程式中計算較少,那麼我們可以通過spark.memory.storage適當調大Storage記憶體,或者通過配置spark.memory.fraction整體調大兩者的總記憶體。
5. 不合適任務並行度
假如我們的Spark應用程式中要讀取的表或檔案資料量比較大,而我們沒有配置合適的記憶體大小,並且分配了比較高的併發度和CPU核數,這些資料要在記憶體中計算,這就可能會造成Executor端OOM。
如果任務並行度較低,而某個任務又被分配了較多的資料,也會造成OOM。
參考
相關文章
- Spark學習——問題排查Spark
- Spark任務OOM問題如何解決?SparkOOM
- OOM分析之問題定位(二)OOM
- 記一次oom問題排查OOM
- 【Spark篇】---Spark解決資料傾斜問題Spark
- 記一次OOM問題排查過程OOM
- 關於MASTER=spark://SparkMaster:7077 ./spark-shell問題ASTSpark
- Spark面試題Spark面試題
- 【scala】問題cannot resolve symbol sparkSymbolSpark
- Spark面試題(七)——Spark程式開發調優Spark面試題
- Spark面試題(八)——Spark的Shuffle配置調優Spark面試題
- Spark面試題(四)Spark面試題
- Spark Standalone模式 Master程式掛掉問題Spark模式AST
- Spark之spark shellSpark
- 【Spark篇】---Spark初始Spark
- 網站速度問題排查與定位經驗網站
- 記錄CDH Spark2的spark2-submit的一個No such file or directory問題SparkMIT
- Apache Spark技術實戰之6 -- spark-submit常見問題及其解決ApacheSparkMIT
- Spark 環境問題記錄和解決方法Spark
- Spark SQL中出現 CROSS JOIN 問題解決SparkSQLROS
- Hadoop/Spark相關面試問題總結HadoopSpark面試
- Spark面試題整理(三)Spark面試題
- Spark習題彙總Spark
- Spark on Yarn 和Spark on MesosSparkYarn
- Spark系列 - (3) Spark SQLSparkSQL
- 【Spark實戰】Spark操作HBase問題:java.io.IOException: Non-increasing Bloom keysSparkJavaExceptionOOM
- AIX OOM問題AIOOM
- tikv oom排查過程OOM
- Spark學習進度-Spark環境搭建&Spark shellSpark
- 【Spark】Spark容錯機制Spark
- Spark導論(Spark自學一)Spark
- 提交Spark作業遇到的NoSuchMethodError問題總結SparkError
- sparkSpark
- hive job oom問題HiveOOM
- spark學習筆記--Spark SQLSpark筆記SQL
- Spark記錄(一):Spark全景概述Spark
- Spark開發-Spark核心細說Spark
- Spark開發-spark環境搭建Spark