Spark的效能調優
下面這些關於Spark的效能調優項,有的是來自官方的,有的是來自別的的工程師,有的則是我自己總結的。
Data Serialization,預設使用的是Java Serialization,這個程式設計師最熟悉,但是效能、空間表現都比較差。還有一個選項是Kryo Serialization,更快,壓縮率也更高,但是並非支援任意類的序列化。
Memory Tuning,Java物件會佔用原始資料2~5倍甚至更多的空間。最好的檢測物件記憶體消耗的辦法就是建立RDD,然後放到cache裡面去,然後在UI 上面看storage的變化;當然也可以使用SizeEstimator來估算。使用-XX:+UseCompressedOops選項可以壓縮指標(8 位元組變成4位元組)。在呼叫collect等等API的時候也要小心——大塊資料往記憶體拷貝的時候心裡要清楚。
GC調優。列印GC資訊:-verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps。預設60%的executor記憶體可以被用來作為RDD的快取,因此只有40%的記憶體可以被用來作為物件建立的空間,這一點可以通過設定spark.storage.memoryFraction改變。如果有很多小物件建立,但是這些物件在不完全GC的過程中就可以回收,那麼增大Eden區會有一定幫助。如果有任務從HDFS拷貝資料,記憶體消耗有一個簡單的估算公式——比如HDFS的block size是64MB,工作區內有4個task拷貝資料,而解壓縮一個block要增大3倍大小,那麼記憶體消耗就是:4*3*64MB。另外,工作中遇到過這樣的一個問題:GC預設情況下有一個限制,預設是GC時間不能超過2%的CPU時間,但是如果大量物件建立(在Spark裡很容易出現,程式碼模式就是一個RDD轉下一個RDD),就會導致大量的GC時間,從而出現OutOfMemoryError: GC overhead limit exceeded,可以通過設定-XX:-UseGCOverheadLimit關掉它。
Level of Parallelism。Spark根據要處理的檔案大小設定map task的數量(也可以通過SparkContext.textFile顯式指定),並且使用最大的parent RDD的分割槽數量來執行reduce操作。設定level of parallelism或者屬性spark.default.parallelism來改變並行級別,通常來說,每一個CPU核可以分配2~3個task。
Reduce Task的記憶體使用。在某些情況下reduce task特別消耗記憶體,比如當shuffle出現的時候,比如sortByKey、groupByKey、reduceByKey和join等,要在記憶體裡面建立一個巨大的hash table。其中一個解決辦法是增大level of parallelism,這樣每個task的輸入規模就相應減小。
Broadcasting Large Variables。在task使用靜態大物件的時候,可以把它broadcast出去。Spark會列印序列化後的大小,通常來說如果它超過20KB就值得這麼做。有一種常見情形是,一個大表join一個小表,把小表broadcast後,大表的資料就不需要在各個node之間瘋跑,安安靜靜地呆在本地等小表broadcast過來就好了。
Data Locality。資料和程式碼要放到一起才能處理,通常程式碼總比資料要小一些,因此把程式碼送到各處會更快。Data Locality是資料和處理的程式碼在屋裡空間上接近的程度:PROCESS_LOCAL(同一個JVM)、NODE_LOCAL(同一個node,比如資料在HDFS上,但是和程式碼在同一個node)、NO_PREF、RACK_LOCAL(不在同一個server,但在同一個機架)、ANY。當然優先順序從高到低,但是如果在空閒的executor上面沒有未處理資料了,那麼就有兩個選擇:(1)要麼等如今繁忙的CPU閒下來處理儘可能“本地”的資料,(1)要麼就不等直接啟動task去處理相對遠端的資料。預設當這種情況發生Spark會等一會兒(spark.locality),即策略(1),如果繁忙的CPU停不下來,就會執行策略(2)。
檔案儲存和讀取的優化。比如對於一些case而言,如果只需要某幾列,使用rcfile和parquet這樣的格式會大大減少檔案讀取成本。再有就是儲存檔案到S3上或者HDFS上,可以根據情況選擇更合適的格式,比如壓縮率更高的格式。
檔案分片。比如在S3上面就支援檔案以分片形式存放,字尾是partXX。使用coalesce方法來設定分成多少片,這個調整成並行級別或者其整數倍可以提高讀寫效能。但是太高太低都不好,太低了沒法充分利用S3並行讀寫的能力,太高了則是小檔案太多,預處理、合併、連線建立等等都是時間開銷啊,讀寫還容易超過throttle。
Spark的Speculation。通過設定spark.speculation等幾個相關選項,可以讓Spark在發現某些task執行特別慢的時候,可以在不等待完成的情況下被重新執行,最後相同的task只要有一個執行完了,那麼最快執行完的那個結果就會被採納。
減少Shuffle。其實Spark的計算往往很快,但是大量開銷都花在網路和IO上面,而shuffle就是一個典型。舉個例子,如果(k, v1) join (k, v2) => (k, v3),那麼,這種情況其實Spark是優化得非常好的,因為需要join的都在一個node的一個partition裡面,join很快完成,結果也是在同一個node(這一系列操作可以被放在同一個stage裡面)。但是如果資料結構被設計為(obj1) join (obj2) => (obj3),而其中的join條件為obj1.column1 == obj2.column1,這個時候往往就被迫shuffle了,因為不再有同一個key使得資料在同一個node上的強保證。在一定要shuffle的情況下,儘可能減少shuffle前的資料規模,比如這個避免groupByKey的例子。
合理的partition。運算過程中資料量時大時小,選擇合適的partition數量關係重大,如果太多partition就導致有很多小任務和空任務產生;如果太少則導致運算資源沒法充分利用,必要時候可以使用repartition來調整,不過它也不是沒有代價的,其中一個最主要代價就是shuffle。再有一個常見問題是資料大小差異太大,這種情況主要是資料的partition的key其實取值並不均勻造成的(預設使用 HashPartitioner),需要改進這一點,比如重寫hash演算法。測試的時候想知道partition的數量可以呼叫 rdd.partitions().size()獲知。
其它一些內容。同事發現Spark1.0.1的速度居然比Spark1.1和1.2快很多,而Spark1.2則比前幾個版本要吃掉多得多的記憶體。
可供參考的文件:官方調優文件Tuning Spark,Spark配置的官方文件,Spark Programming Guide,JVMGC調優文件,JVM效能調優文件,How-to: Tune Your Apache Spark Jobs part-1 & part-2。
相關文章
- Spark 效能調優--資源調優Spark
- Spark學習——效能調優(一)Spark
- Spark學習——效能調優(二)Spark
- Spark學習——效能調優(三)Spark
- Spark(十三) Spark效能調優之RDD持久化Spark持久化
- 快取Apache Spark RDD - 效能調優快取ApacheSpark
- spark效能調優指南高階篇Spark
- Spark 效能調優--開發階段Spark
- Spark效能調優——9項基本原則Spark
- Spark shuffle調優Spark
- Spark效能優化Spark優化
- spark調優-背壓Spark
- spark效能優化(一)Spark優化
- Spark面試題(八)——Spark的Shuffle配置調優Spark面試題
- Spark效能最佳化篇三:資料傾斜調優Spark
- Spark效能調優-RDD運算元調優篇(深度好文,面試常問,建議收藏)Spark面試
- 1,Spark引數調優Spark
- 【效能調優】效能測試、分析與調優基礎
- spark學習筆記--Spark調優與除錯Spark筆記除錯
- Spark面試題(七)——Spark程式開發調優Spark面試題
- Spark Streaming調優引數及最佳實踐深入剖析-Spark商業調優實戰Spark
- Spark應用程式開發引數調優深入剖析-Spark商業調優實戰Spark
- ElasticSearch效能調優Elasticsearch
- adnroid效能調優
- spark效能優化幾點注意Spark優化
- 個推技術實踐 | Spark效能調優看這篇,效能提升60%↑ 成本降低50%↓Spark
- Spark 3.x Spark Core詳解 & 效能優化Spark優化
- Spark效能優化:優化資料結構Spark優化資料結構
- 效能調優的通用準則
- 效能調優學習之硬體調優
- 效能調優實戰
- Linux之效能調優Linux
- 效能監控調優
- linux調優效能命令Linux
- .Net效能調優-ArrayPool
- .Net效能調優-MemoryPool
- 驢行千里不洗沙塵,尚矽谷Spark效能調優教程釋出Spark
- 個推技術分享:效能提升60%↑ 成本降低50%↓ Spark效能調優看這篇就夠了!Spark
- Spark效能優化:診斷記憶體的消耗Spark優化記憶體