Spark 效能調優--資源調優
資源調優
在開發完Spark作業之後,就該為作業配置合適的資源了。Spark的資源引數,基本都可以在spark-submit命令中作為引數設定
Spark作業基本執行原理
Spark作業基本執行原理
spark-submit提交一個Spark作業之後,這個作業就會啟動一個對應的Driver程式
根據你使用的部署模式(deploy-mode:client/cluster)不同,Driver程式可能在本地啟動,也可能在叢集中某個工作節點上啟動
Driver程式本身會根據我們設定的引數,佔有一定數量的記憶體和CPU Core
Driver程式要做的第一件事情,就是向叢集管理器(可以是Spark Standalone叢集,也可以是YARN)申請執行Spark作業需要使用的資源。資源指的就是Executor程式。在各個工作節點上,啟動一定數量的Executor程式,每個Executor程式都佔有一定數量的記憶體和CPU Core
在申請到了作業執行所需的資源之後,Driver程式就會開始排程和執行我們編寫的作業程式碼了
Driver程式會將我們編寫的Spark作業程式碼分拆為多個Stage,每個Stage執行一部分程式碼片段,併為每個Stage建立一批Task,然後將這些Task分配到各個Executor程式中執行
Task是最小的計算單元,負責執行一模一樣的計算邏輯(也就是我們編寫的某個程式碼片段),只是每個Task處理的資料不同而已。一個Stage的所有Task都執行完畢之後,會在各個節點本地的磁碟檔案中寫入計算中間結果,然後Driver就會排程執行下一個Stage。下一個Stage的Task的輸入資料就是上一個Stage輸出的中間結果
Spark是根據Shuffle類運算元來進行Stage的劃分,Shuffle運算元執行之前的程式碼會被劃分為一個Stage
Executor的記憶體主要分為三塊
- 第一塊是讓task執行我們自己編寫的程式碼時使用,預設是佔Executor總記憶體的20%
- 第二塊是讓Task透過Shuffle過程拉取了上一個Stage的Task的輸出後,進行聚合等操作時使用,預設也是佔Executor總記憶體的20%
- 第三塊是讓RDD持久化時使用,預設佔Executor總記憶體的60%
參考
Task的執行速度是跟每個Executor程式的CPU Core數量有直接關係的。一個CPU Core同一時間只能執行一個執行緒。而每個Executor程式上分配到的多個Task,都是以每個Task一條執行緒的方式,多執行緒併發執行的。如果CPU Core數量比較充足,而且分配到的Task數量比較合理,那麼通常來說,可以比較快速和高效地執行完這些Task執行緒
資源引數調優
num-executors
設定Spark作業總共要用多少個Executor程式來執行
Driver在向YARN叢集管理器申請資源時,YARN叢集管理器會盡可能按照你的設定來在叢集的各個工作節點上,啟動相應數量的Executor程式
每個Spark作業的執行一般設定50~100個左右(根據叢集的規模)的Executor程式比較合適,設定太少或太多的Executor程式都不好。設定的太少,無法充分利用叢集資源;設定的太多的話,大部分佇列可能無法給予充分的資源
executor-memory
設定每個Executor程式的記憶體
Executor記憶體的大小,很多時候直接決定了Spark作業的效能,而且跟常見的JVM OOM異常,也有直接的關聯
每個Executor程式的記憶體設定4G~8G較為合適,num-executors乘以executor-memory,是不能超過佇列的最大記憶體量的,Spark叢集可以設定每個executor最多使用的記憶體大小。如果你是跟團隊裡其他人共享這個資源佇列,那麼申請的記憶體量最好不要超過資源佇列最大總記憶體的1/3~1/2
executor-cores
設定每個Executor程式的CPU core數量
決定了每個Executor程式並行執行task執行緒的能力
數量設定為2~4個較為合適,依據資源佇列的最大CPU Core限制是多少,再依據設定的Executor數量,來決定每個Executor程式可以分配到幾個CPU Core
driver-memory
設定Driver程式的記憶體
Driver的記憶體通常來說不設定,或者設定1G左右應該就夠了
如果需要使用 collect 運算元將RDD的資料全部拉取到Driver上進行處理,那麼必須確保Driver的記憶體足夠大,否則會出現OOM記憶體溢位的問題
spark.default.parallelism
設定每個stage的預設task數量
不去設定這個引數,那麼Spark根據底層HDFS的block數量來設定task的數量,預設是一個HDFS block對應一個task,通常來說,Spark預設設定的數量是偏少的
設定該引數為num-executors * executor-cores的2~3倍較為合適
如果task數量偏少的話,Executor程式可能根本就沒有task執行,也就是白白浪費了資源
spark.storage.memoryFraction
設定RDD持久化資料在Executor記憶體中能佔的比例,預設是0.6
根據你選擇的不同的持久化策略,如果記憶體不夠時,可能資料就不會持久化,或者資料會寫入磁碟
如果Spark作業中,有較多的RDD持久化操作,該引數的值可以適當提高一些
如果Spark作業中的Shuffle類操作比較多,而持久化操作比較少,那麼這個引數的值適當降低一些比較合適
如果發現作業由於頻繁的GC導致執行緩慢(透過Spark WebUI可以觀察到作業的GC耗時),意味著Task執行使用者程式碼的記憶體不夠用,那麼同樣建議調低這個引數的值
spark.shuffle.memoryFraction
設定Shuffle過程中一個task拉取到上個Stage的Task的輸出後,進行聚合操作時能夠使用的Executor記憶體的比例,預設是0.2
Shuffle操作在進行聚合時,如果發現使用的記憶體超出了這個20%的限制,那麼多餘的資料就會溢寫到磁碟檔案中去,此時就會極大地降低效能
如果Spark作業中的RDD持久化操作較少,Shuffle操作較多時,建議降低持久化操作的記憶體佔比,提高Shuffle操作的記憶體佔比比例
如果發現作業由於頻繁的GC導致執行緩慢,意味著Task執行使用者程式碼的記憶體不夠用,那麼同樣建議調低這個引數的值
示例
#args : /usr/local/spark/bin/spark-submit --class Process --master yarn-cluster --name Process --queue fetech --num-executors 20 --driver-memory 5g --executor-memory 4g --executor-cores 2 --conf spark.default.parallelism=500 --conf spark.storage.memoryFraction=0.5 /process.jar $1 $2 $3 $4
作者:Alex90
連結:
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/3407/viewspace-2818657/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Spark學習——效能調優(一)Spark
- Spark學習——效能調優(二)Spark
- Spark學習——效能調優(三)Spark
- Spark(十三) Spark效能調優之RDD持久化Spark持久化
- Spark 效能調優--開發階段Spark
- spark效能調優指南高階篇Spark
- 快取Apache Spark RDD - 效能調優快取ApacheSpark
- Spark shuffle調優Spark
- Spark效能調優——9項基本原則Spark
- spark調優-背壓Spark
- Spark效能最佳化篇三:資料傾斜調優Spark
- 【效能調優】效能測試、分析與調優基礎
- 效能調優學習之硬體調優
- Flink - 資源配置調優
- adnroid效能調優
- ElasticSearch效能調優Elasticsearch
- 1,Spark引數調優Spark
- Spark效能調優-RDD運算元調優篇(深度好文,面試常問,建議收藏)Spark面試
- Linux之效能調優Linux
- 效能監控調優
- .Net效能調優-MemoryPool
- .Net效能調優-ArrayPool
- linux調優效能命令Linux
- 效能調優實戰
- Spark Streaming調優引數及最佳實踐深入剖析-Spark商業調優實戰Spark
- Spark應用程式開發引數調優深入剖析-Spark商業調優實戰Spark
- Nginx安全優化與效能調優Nginx優化
- HBase資料庫效能調優OW資料庫
- java效能調優記錄Java
- Kafka 線上效能調優Kafka
- 2. 效能調優概述
- android效能調優詳解Android
- 效能調優命令之jstackJS
- 淺談Nginx效能調優Nginx
- solr研磨之效能調優Solr
- TiDB 效能分析&效能調優&優化實踐大全TiDB優化
- 掌握Oracle資料庫效能調優方法Oracle資料庫
- Spark面試題(七)——Spark程式開發調優Spark面試題