Spark 資源調(diào)優(yōu)

Executor內(nèi)存使用

image.png

因此Executor的內(nèi)存主要分為三塊:

  • 第一塊是讓task執(zhí)行我們自己編寫的代碼時使用,默認(rèn)是占Executor總內(nèi)存的20%
  • 第二塊是讓task通過shuffle過程拉取了上一個stage的task的輸出后,進(jìn)行聚合等操作時使用,默認(rèn)也是占Executor總內(nèi)存的20%
  • 第三塊是讓RDD持久化時使用,默認(rèn)占Executor總內(nèi)存的60%

資源參數(shù)調(diào)優(yōu)

  • num-executors
    參數(shù)說明:該參數(shù)用于設(shè)置Spark作業(yè)總共要用多少個Executor進(jìn)程來執(zhí)行
    參數(shù)調(diào)優(yōu)建議:每個Spark作業(yè)的運行一般設(shè)置50~100個左右的Executor進(jìn)程比較合適,設(shè)置太少或太多的Executor進(jìn)程都不好。設(shè)置的太少,無法充分利用集群資源;設(shè)置的太多的話,大部分隊列可能無法給予充分的資源。

  • executor-memory
    參數(shù)說明:該參數(shù)用于設(shè)置每個Executor進(jìn)程的內(nèi)存。Executor內(nèi)存的大小,很多時候直接決定了Spark作業(yè)的性能,而且跟常見的JVM OOM異常,也有直接的關(guān)聯(lián)。
    參數(shù)調(diào)優(yōu)建議:每個Executor進(jìn)程的內(nèi)存設(shè)置4G~8G較為合適。但是這只是一個參考值,具體的設(shè)置還是得根據(jù)不同部門的資源隊列來定。可以看看自己團(tuán)隊的資源隊列的最大內(nèi)存限制是多少,num-executors乘以executor-memory,是不能超過隊列最大內(nèi)存量的。此外,如果你是跟團(tuán)隊里其他人共享這個資源隊列,那么申請的內(nèi)存量最好不要超過資源隊列最大總內(nèi)存1/3~1/2,避免你自己的Spark作業(yè)占用了隊列所有的資源,導(dǎo)致別的同學(xué)的作業(yè)無法運行。

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

  • driver-memory
    參數(shù)說明:該參數(shù)用于設(shè)置Driver進(jìn)程的內(nèi)存。
    參數(shù)調(diào)優(yōu)建議:Driver的內(nèi)存通常來說不設(shè)置,或者設(shè)置1G左右應(yīng)該就夠了。唯一需要注意的一點是,如果需要使用collect算子將RDD的數(shù)據(jù)全部拉取到Driver上進(jìn)行處理,那么必須確保Driver的內(nèi)存足夠大,否則會出現(xiàn)OOM內(nèi)存溢出的問題。

  • spark.default.parallelism
    參數(shù)說明:該參數(shù)用于設(shè)置每個stage的默認(rèn)task數(shù)量。這個參數(shù)極為重要,如果不設(shè)置可能會直接影響你的Spark作業(yè)性能。
    參數(shù)調(diào)優(yōu)建議:Spark作業(yè)的默認(rèn)task數(shù)量為500~1000個較為合適。很多同學(xué)常犯的一個錯誤就是不去設(shè)置這個參數(shù),那么此時就會導(dǎo)致Spark自己根據(jù)底層HDFS的block數(shù)量來設(shè)置task的數(shù)量,默認(rèn)是一個HDFS block對應(yīng)一個task。通常來說,Spark默認(rèn)設(shè)置的數(shù)量是偏少的(比如就幾十個task),如果task數(shù)量偏少的話,就會導(dǎo)致你前面設(shè)置好的Executor的參數(shù)都前功盡棄。試想一下,無論你的Executor進(jìn)程有多少個,內(nèi)存和CPU有多大,但是task只有1個或者10個,那么90%的Executor進(jìn)程可能根本就沒有task執(zhí)行,也就是白白浪費了資源!因此Spark官網(wǎng)建議的設(shè)置原則是,設(shè)置該參數(shù)為num-executors * executor-cores2~3倍較為合適,比如Executor的總CPU core數(shù)量為300個,那么設(shè)置1000個task是可以的,此時可以充分地利用Spark集群的資源

官方是推薦,task數(shù)量,設(shè)置成spark application總cpu core數(shù)量的2~3倍,比如150個cpu core,基本要設(shè)置task數(shù)量為300~500;
實際情況,與理想情況不同的,有些task會運行的快一點,比如50s就完了,有些task,可能會慢一點,要1分半才運行完,所以如果你的task數(shù)量,剛好設(shè)置的跟cpu core數(shù)量相同,可能還是會導(dǎo)致資源的浪費,因為,比如150個task,10個先運行完了,剩余140個還在運行,但是這個時候,有10個cpu core就空閑出來了,就導(dǎo)致了浪費。那如果task數(shù)量設(shè)置成cpu core總數(shù)的2~3倍,那么一個task運行完了以后,另一個task馬上可以補上來,就盡量讓cpu core不要空閑,同時也是盡量提升spark作業(yè)運行的效率和速度,提升性能。

  • spark.storage.memoryFraction
    參數(shù)說明:該參數(shù)用于設(shè)置RDD持久化數(shù)據(jù)在Executor內(nèi)存中能占的比例,默認(rèn)是0.6。也就是說,默認(rèn)Executor 60%的內(nèi)存,可以用來保存持久化的RDD數(shù)據(jù)。根據(jù)你選擇的不同的持久化策略,如果內(nèi)存不夠時,可能數(shù)據(jù)就不會持久化,或者數(shù)據(jù)會寫入磁盤。
    參數(shù)調(diào)優(yōu)建議
  1. 如果Spark作業(yè)中,有較多的RDD持久化操作,該參數(shù)的值可以適當(dāng)提高一些,保證持久化的數(shù)據(jù)能夠容納在內(nèi)存中。避免內(nèi)存不夠緩存所有的數(shù)據(jù),導(dǎo)致數(shù)據(jù)只能寫入磁盤中,降低了性能。
  2. 但是如果Spark作業(yè)中的shuffle類操作比較多,而持久化操作比較少,那么這個參數(shù)的值適當(dāng)降低一些比較合適。此外,
  3. 如果發(fā)現(xiàn)作業(yè)由于頻繁的gc導(dǎo)致運行緩慢(通過spark web ui可以觀察到作業(yè)的gc耗時),意味著task執(zhí)行用戶代碼的內(nèi)存不夠用,那么同樣建議調(diào)低這個參數(shù)的值。
  • spark.shuffle.memoryFraction
    參數(shù)說明:該參數(shù)用于設(shè)置shuffle過程中一個task拉取到上個stage的task的輸出后,進(jìn)行聚合操作時能夠使用的Executor內(nèi)存的比例,默認(rèn)是0.2。也就是說,Executor默認(rèn)只有20%的內(nèi)存用來進(jìn)行該操作。shuffle操作在進(jìn)行聚合時,如果發(fā)現(xiàn)使用的內(nèi)存超出了這個20%的限制,那么多余的數(shù)據(jù)就會溢寫到磁盤文件中去,此時就會極大地降低性能
    參數(shù)調(diào)優(yōu)建議:如果Spark作業(yè)中的RDD持久化操作較少,shuffle操作較多時,建議降低持久化操作的內(nèi)存占比,提高shuffle操作的內(nèi)存占比比例,避免shuffle過程中數(shù)據(jù)過多時內(nèi)存不夠用,必須溢寫到磁盤上,降低了性能。此外,如果發(fā)現(xiàn)作業(yè)由于頻繁的gc導(dǎo)致運行緩慢,意味著task執(zhí)行用戶代碼的內(nèi)存不夠用,那么同樣建議調(diào)低這個參數(shù)的值。

資源參數(shù)的調(diào)優(yōu),沒有一個固定的值,需要同學(xué)們根據(jù)自己的實際情況(包括Spark作業(yè)中的shuffle操作數(shù)量、RDD持久化操作數(shù)量以及spark web ui中顯示的作業(yè)gc情況),同時參考本篇文章中給出的原理以及調(diào)優(yōu)建議,合理地設(shè)置上述參數(shù)。
資源參數(shù)參考示例

以下是一份spark-submit命令的示例,大家可以參考一下,并根據(jù)自己的實際情況進(jìn)行調(diào)節(jié):

./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 \

轉(zhuǎn)自:
http://www.lxweimin.com/p/c53a1762ad91
https://tech.meituan.com/2016/04/29/spark-tuning-basic.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。