Spark 遇到OOM怎麼解決

2021-09-25 23:00:42 字數 1480 閱讀 9159

map執行中記憶體溢位

shuffle後記憶體溢位

spark 記憶體模型:

spark在乙個executor中的記憶體分為三塊:

一塊是execution記憶體,

一塊是storage記憶體,

一塊是other記憶體。

當spark程式中,存在過多的小任務的時候,可以通過 rdd.coalesce方法,收縮合併分割槽,減少分割槽的個數,減小任務排程成本,避免shuffle導致,比rdd.repartition效率提高不少。

這種溢位的原因是在單個map中產生了大量的物件導致的。

例如:rdd.map(x=>for(i <- 1 to 10000) yield i.tostring),這個操作在rdd中,每個物件都產生了10000個物件,這肯定很容易產生記憶體溢位的問題。針對這種問題,在不增加記憶體的情況下,可以通過減少每個task的大小,以便達到每個task即使產生大量的物件executor的記憶體也能夠裝得下。具體做法可以在會產生大量物件的map操作之前呼叫repartition方法,分割槽成更小的塊傳入map。例如:rdd.repartition(10000).map(x=>for(i <- 1 to 10000) yield i.tostring)。

這是我最近才遇到的乙個問題,因為hdfs中不適合存小問題,所以spark計算後如果產生的檔案太小,我們會呼叫coalesce合併檔案再存入hdfs中。但是這會導致乙個問題,例如在coalesce之前有100個檔案,這也意味著能夠有100個task,現在呼叫coalesce(10),最後只產生10個檔案,因為coalesce並不是shuffle操作,這意味著coalesce並不是按照我原本想的那樣先執行100個task,再將task的執行結果合併成10個,而是從頭到位只有10個task在執行,原本100個檔案是分開執行的,現在每個task同時一次讀取10個檔案,使用的記憶體是原來的10倍,這導致了oom。解決這個問題的方法是令程式按照我們想的先執行100個task再將結果合併成10個檔案,這個問題同樣可以通過repartition解決,調整repartition(10)

shuffle記憶體溢位的情況可以說都是shuffle後,單個檔案過大導致的。

在spark中,join,reducebykey這一型別的過程,都會有shuffle的過程,在shuffle的使用,需要傳入乙個partitioner,大部分spark中的shuffle操作,預設的partitioner都是hashpatitioner,預設值是父rdd中最大的分割槽數,這個引數通過spark.default.parallelism控制(在spark-sql中用spark.sql.shuffle.partitions) , spark.default.parallelism引數只對hashpartitioner有效,所以如果是別的partitioner或者自己實現的partitioner就不能使用spark.default.parallelism這個引數來控制shuffle的併發量了。如果是別的partitioner導致的shuffle記憶體溢位,就需要從partitioner的**增加partitions的數量。

Spark面對OOM問題的解決方法及優化總結

記憶體溢位解決方法 1.map過程產生大量物件導致記憶體溢位 這種溢位的原因是在單個map中產生了大量的物件導致的,例如 rdd.map x for i 1 to 10000 yield i.tostring 這個操作在rdd中,每個物件都產生了10000個物件,這肯定很容易產生記憶體溢位的問題。針...

Spark 中OOM的現象 原因 解決方案和總結

參考 spark的executor的container記憶體有兩大部分組成 堆外記憶體和executor記憶體。堆外記憶體 有spark.yarn.executor.memeoryoverhead引數設定。如果沒有設定,則使用 val executormemoryoverhead sparkconf...

oom問題解決

dalvik虛擬機會為應用程式分配固定大小的heap 如果使用超過了這個heap的大小,且沒有可被 物件,就會報oom。多張較大會迅速占用空間造成oom。我們可以使用一下的方法來減少這種情況的產生 1.減少單張的大小,根據螢幕大小來對bitmap做resize。private void setima...