Executor內(nèi)存使用
因此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-cores
的2~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)建議:
- 如果Spark作業(yè)中,有較多的RDD持久化操作,該參數(shù)的值可以適當(dāng)提高一些,保證持久化的數(shù)據(jù)能夠容納在內(nèi)存中。避免內(nèi)存不夠緩存所有的數(shù)據(jù),導(dǎo)致數(shù)據(jù)只能寫入磁盤中,降低了性能。
- 但是如果Spark作業(yè)中的shuffle類操作比較多,而持久化操作比較少,那么這個參數(shù)的值適當(dāng)降低一些比較合適。此外,
- 如果發(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