spark-25.spark調優_3_spark資源配置

1.資源運行中的幾種情況

  1. 實踐中跑的SparkJob,有的特別慢,查看CPU利用率很低,可以嘗試減少每個executor佔用的CPU core的數量,增加並行的executor數量,同時配合增加分片,整體上增加了CPU的利用率,加快數據處理速度。
  2. 發現某個job很容易發生內存溢出,我們就增大分片數量,從而減少了每片數據的規模,同時還減少並行的executor數量,這樣相同的內存資源分配給數量更少的executor,相當於增加了每個task的內存分配,這樣運行速度可能慢了些,但是總比OOM強。
  3. 數據量特別少,有大量的小文件生成,就減少文件分片,沒必要創建那麼多task,這種情況,如果只是最原始的input比較小,一般都能被注意到;但是,如果是在運算過程中,比如應用某一個reduceBy或者某個filter以後,數據大量減少,這種低效情況就很少被留意到。

2.運行資源優化配置

一個CPU core同一時間只能執行一個線程。而每個Executor進程上分配到的多個task,都是以每個task一條線程的方式,多線程併發的。一個應用提交的時候設置多大的內存,設置多少core,設置幾個executor。這些都是調優過程中需要進行設置的。
如:

./bin/spark-submit \
  --master yarn-cluster \
  --num-executors 100 \
  --executor-memory 6G \
  --executor-cores 4 \
  --driver-memory 1G \
  --conf spark.default.parallelism=1000 \
  --conf spark.storage.memoryFraction=0.5 \
  --conf spark.shuffle.memoryFraction=0.3 \ 

num-executors

  • 參數說明:
    用於設置spark作業總共需要用多少個Executor進程來執行。Driver在向YARN集羣管理器申請資源時,YARN集羣管理器會盡可能按照你的設置來在集羣的各個工作節點上,啓動相應數量的Executor進程。這個參數非常重要,如果不設置的話,默認只會給你啓動少量的Executor進程,此時你的spark作業的運行速度是非常慢的。
  • 調優建議:
    每個spark作業的運行一般設置50-100個左右的Executor進程比較合適,設置太少或太多的Executor進程都不好。設置的太少,無法充分利用集羣資源;設置的太多的話,大部分隊列可能無法給予充分的資源。

executor-memory

  • 參數說明:
    該參數用於設置每個Executor進程的內存。Executor內存的大小,很多時候直接決定了Spark作業的性能,而且跟常見的JVM OOM異常,也有直接的關聯。
  • 參數調優建議:
    每個Executor進程的內存設置4G-8G較爲合適。但是這只是一個參考值,具體的設置還是得根據不同部門的資源隊列來定。可以看看自己團隊的資源隊列的最大內存限制是多少,num-executors乘以executor-memory,是不能超過隊列的最大內存量的。此外,如果你是跟團隊裏其他人共享這個資源隊列,那麼申請的內存量最好不要超過資源隊列最大總內存的1/3~1/2,避免你自己的Spark作業佔用了隊列所有的資源,導致別的同事的作業無法運行。

executor-cores

  • 參數說明:
    該參數用於設置每個Executor進程的CPU core數量。這個參數決定了每個Executor進程並行執行task線程的能力。因爲每個CPU core同一時間只能執行一個task線程,因此每個Executor進程的CPU core數量越多,越能夠快速地執行完分配給自己的所有task線程。
  • 參數調優建議:
    Executor的CPU core數量設置爲2~4個較爲合適。同樣得根據不同部門的資源隊列來定,可以看看自己的資源隊列的最大CPU core限制是多少,再依據設置的Executor數量,來決定每個Executor進程可以分配到幾個CPU core。同樣建議,如果是跟他人共享這個隊列,那麼num-executors * executor-cores不要超過隊列總CPU core的1/3~1/2左右比較合適,也是避免影響其他同事的作業運行。

driver-memory

  • 參數說明:
    該參數用於設置Driver進程的內存。
  • 參數調優建議:
    Driver的內存通常來說不設置,或者設置1G左右應該就夠了。唯一需要注意的一點是,如果需要使用collect算子將RDD的數據全部拉取到Driver上進行處理,那麼必須確保Driver的內存足夠大,否則會出現OOM內存溢出的問題。

spark.default.parallelism

  • 參數說明:
    該參數用於設置每個stage的默認task數量,也可以認爲是分區數。這個參數極爲重要,如果不設置可能會直接影響你的Spark作業性能。
  • 參數調優建議:
    Spark作業的默認task數量爲500~1000個較爲合適。很多同學常犯的一個錯誤就是不去設置這個參數,那麼此時就會導致Spark自己根據底層HDFS的block數量來設置task的數量,默認是一個HDFS block對應一個task。通常來說,Spark默認設置的數量是偏少的(比如就幾十個task),如果task數量偏少的話,就會導致你前面設置好的Executor的參數都前功盡棄。試想一下,無論你的Executor進程有多少個,內存和CPU有多大,但是task只有1個或者10個,那麼90%的Executor進程可能根本就沒有task執行,也就是白白浪費了資源!因此Spark官網建議的設置原則是,設置該參數爲num-executors * executor-cores的2~3倍較爲合適,比如Executor的總CPU core數量爲300個,那麼設置1000個task是可以的,此時可以充分地利用Spark集羣的資源。

spark.storage.memoryFraction

  • 參數說明:
    該參數用於設置RDD持久化數據在Executor內存中能佔的比例,默認是0.6。也就是說,默認Executor 60%的內存,可以用來保存持久化的RDD數據。根據你選擇的不同的持久化策略,如果內存不夠時,可能數據就不會持久化,或者數據會寫入磁盤。
  • 參數調優建議:
    如果Spark作業中,有較多的RDD持久化操作,該參數的值可以適當提高一些,保證持久化的數據能夠容納在內存中。避免內存不夠緩存所有的數據,導致數據只能寫入磁盤中,降低了性能。但是如果Spark作業中的shuffle類操作比較多,而持久化操作比較少,那麼這個參數的值適當降低一些比較合適。此外,如果發現作業由於頻繁的gc導致運行緩慢(通過spark web ui可以觀察到作業的gc耗時),意味着task執行用戶代碼的內存不夠用,那麼同樣建議調低這個參數的值。

spark.shuffle.memoryFraction

  • 參數說明:
    該參數用於設置shuffle過程中一個task拉取到上個stage的task的輸出後,進行聚合操作時能夠使用的Executor內存的比例,默認是0.2。也就是說,Executor默認只有20%的內存用來進行該操作。shuffle操作在進行聚合時,如果發現使用的內存超出了這個20%的限制,那麼多餘的數據就會溢寫到磁盤文件中去,此時就會極大地降低性能。
  • 參數調優建議:
    如果Spark作業中的RDD持久化操作較少,shuffle操作較多時,建議降低持久化操作的內存佔比,提高shuffle操作的內存佔比比例,避免shuffle過程中數據過多時內存不夠用,必須溢寫到磁盤上,降低了性能。此外,如果發現作業由於頻繁的gc導致運行緩慢,意味着task執行用戶代碼的內存不夠用,那麼同樣建議調低這個參數的值。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章