天天看點

Spark程式優化及常見報錯問題分析

在實際的基于Spark平台的大資料分析項目中,為提高程式的運作效率,對程式進行優化是必不可少的,本文基于個人在大資料項目中使用Spark進行程式設計實作的實踐經曆,針對Spark程式優化問題進行總結,具體内容如下所述。

1. 代碼層優化

(1)避免建立多個相同的RDD對象

(2)DAG劃分的多個stage中存在相同的RDD對象,則需要将該RDD對象進行緩存,避免重複計算。

(3)代碼中存在大小表關聯邏輯時,建議使用廣播變量(Broadcast)解決。

(4)涉及廣播變量的map過程,強烈建議使用mapPartitions函數替代map函數,否則在大規模資料場景下,容易導緻叢集節點記憶體溢出甚至節點宕掉。

(5)涉及聚合操作時,合理選擇groupByKey()和reduceByKey()、combineBykey()函數,三者的具體差異及使用詳見文檔(連結:http://blog.csdn.net/zylove2010/article/details/78577333)

(6)使用repartition()函數合理調整RDD的分區數,特别是在涉及shuffle操作時,需根據shuffle過程中map和reduce階段的計算複雜度,增大或減少RDD的分區數,以提高程式的運作效率。總體原則是:合理調整RDD的分區值,充分利用叢集配置設定的計算資源。

2. 任務的資源設定優化

(1)合理設定任務運作時叢集配置設定的資源

一般情況下,叢集的計算資源有限,且叢集資源是多個任務共享的資源池,為避免叢集資源浪費,在向叢集申請資源時需綜合考慮叢集可用資源和預估任務需要的資源。叢集資源主要考慮CPU核數和記憶體大小。

(2)合理設定任務運作時的各種參數

任務送出時,可通過spark-submit指令動态設定相關參數,比如設定JVM的垃圾回收機制、executor心跳連接配接逾時時長等。spark-submit指令的具體使用詳見文檔(連結:http://blog.csdn.net/zylove2010/article/details/78405295)

3. 資料傾斜問題專題優化

資料傾斜問題是指在spark任務的運作過程中,某個shuffle階段的大量資料被配置設定給某個或某幾個executor進行處理,導緻這幾個executor的運作時長遠遠超過其他executor。

由于spark中shuffle階段之間是串行操作,隻有目前階段的所有任務計算完成後才能進入下一個shuffle階段,是以目前階段的運作時長由耗時最長的executor決定,資料傾斜會使得整個Spark任務的耗時過長,甚至有記憶體溢出的風險導緻任務報錯。資料傾斜問題對整個程式的性能影響非常大,是以都會将其作為一個spark優化專題進行講解,詳細的優化文章網上有很多,在這裡僅抛磚引玉。

(1)資料傾斜問題的原因核查

如何發現spark任務存在資料傾斜問題?常見的方法是通過觀察spark任務的運作日志記錄進行核查。比如通過spark自帶的web UI工具檢視正在運作的spark程式的詳細狀态,若某個stage階段中有一個executor運作時長遠遠大于其他executor,則該stage存在資料傾斜問題,可定位到該stage對應的程式代碼處進行詳細核查。

(2)利用資料預處理方法徹底解決資料傾斜問題

資料傾斜問題的主要原因是資料的分布不均衡導緻,常見的解決方法是針對資料的分布不均衡進行預處理操作使其變得均衡。

4. 熟練使用web UI核查spark程式的運作狀态

web UI的預設位址為:http://master:8080,在浏覽器輸入該網址即可,其中master為叢集主節點的IP。界面如下圖所示:

Spark程式優化及常見報錯問題分析

5. 程式運作時出現的各種問題彙總

(1)executor-memory設定偏小(圖檔截取executor所在節點的資源占用情況)

Spark程式優化及常見報錯問題分析

在yarn模式下,executor會直接被kill掉,導緻任務運作失敗。

解決辦法:在送出任務時将executor-memory參數的值調大一些即可解決。

(2)任務的并發度設定太高

Spark程式優化及常見報錯問題分析

圖中cpu資源占用過高,導緻任務堵塞。主要原因是配置設定的cpu核數有限,但任務的并發度很高,使得cpu處理不過來,出現任務堵塞,最終導緻任務失敗。

解決辦法:定位發生該問題的代碼段,通過repartition()方式調低RDD的分區值或者在任務送出時申請更多的cpu核數。

(3)executor假死問題

Spark程式優化及常見報錯問題分析

圖中出現executor心跳連接配接逾時,導緻任務運作失敗。主要原因是設定的executor-memory過大或者是partition設定大太小,導緻executor端的JVM全局回收時長過長,導緻其耗時超過executor的心跳時長,使得master誤認為executor端出現異常而将executor 正運作的任務kill掉。

解決辦法:定位發生該問題的代碼段,合理調整executor-memory和RDD的partition值。

繼續閱讀