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

spark.shuffle.file.buffer

默認(rèn)值:32k
參數(shù)說明:該參數(shù)用于設(shè)置shuffle write task的BufferedOutputStream的buffer緩沖大小。將數(shù)據(jù)寫到磁盤文件之前,會先寫入buffer緩沖中,待緩沖寫滿之后,才會溢寫到磁盤。
調(diào)優(yōu)建議:如果作業(yè)可用的內(nèi)存資源較為充足的話,可以適當(dāng)增加這個(gè)參數(shù)的大?。ū热?4k),從而減少shuffle write過程中溢寫磁盤文件的次數(shù),也就可以減少磁盤IO次數(shù),進(jìn)而提升性能。在實(shí)踐中發(fā)現(xiàn),合理調(diào)節(jié)該參數(shù),性能會有1%~5%的提升。

spark.reducer.maxSizeInFlight

默認(rèn)值:48m
參數(shù)說明:該參數(shù)用于設(shè)置shuffle read task的buffer緩沖大小,而這個(gè)buffer緩沖決定了每次能夠拉取多少數(shù)據(jù)。
調(diào)優(yōu)建議:如果作業(yè)可用的內(nèi)存資源較為充足的話,可以適當(dāng)增加這個(gè)參數(shù)的大?。ū热?6m),從而減少拉取數(shù)據(jù)的次數(shù),也就可以減少網(wǎng)絡(luò)傳輸?shù)拇螖?shù),進(jìn)而提升性能。在實(shí)踐中發(fā)現(xiàn),合理調(diào)節(jié)該參數(shù),性能會有1%~5%的提升。

spark.shuffle.io.maxRetries

默認(rèn)值:3
參數(shù)說明:shuffle read task從shuffle write task所在節(jié)點(diǎn)拉取屬于自己的數(shù)據(jù)時(shí),如果因?yàn)榫W(wǎng)絡(luò)異常導(dǎo)致拉取失敗,是會自動進(jìn)行重試的。該參數(shù)就代表了可以重試的最大次數(shù)。如果在指定次數(shù)之內(nèi)拉取還是沒有成功,就可能會導(dǎo)致作業(yè)執(zhí)行失敗。
調(diào)優(yōu)建議:對于那些包含了特別耗時(shí)的shuffle操作的作業(yè),建議增加重試最大次數(shù)(比如60次),以避免由于JVM的full gc或者網(wǎng)絡(luò)不穩(wěn)定等因素導(dǎo)致的數(shù)據(jù)拉取失敗。在實(shí)踐中發(fā)現(xiàn),對于針對超大數(shù)據(jù)量(數(shù)十億~上百億)的shuffle過程,調(diào)節(jié)該參數(shù)可以大幅度提升穩(wěn)定性。

spark.shuffle.io.retryWait

默認(rèn)值:5s
參數(shù)說明:具體解釋同上,該參數(shù)代表了每次重試?yán)?shù)據(jù)的等待間隔,默認(rèn)是5s。
調(diào)優(yōu)建議:建議加大間隔時(shí)長(比如60s),以增加shuffle操作的穩(wěn)定性。

spark.shuffle.memoryFraction

默認(rèn)值:0.2
參數(shù)說明:該參數(shù)代表了Executor內(nèi)存中,分配給shuffle read task進(jìn)行聚合操作的內(nèi)存比例,默認(rèn)是20%。
調(diào)優(yōu)建議:在資源參數(shù)調(diào)優(yōu)中講解過這個(gè)參數(shù)。如果內(nèi)存充足,而且很少使用持久化操作,建議調(diào)高這個(gè)比例,給shuffle read的聚合操作更多內(nèi)存,以避免由于內(nèi)存不足導(dǎo)致聚合過程中頻繁讀寫磁盤。在實(shí)踐中發(fā)現(xiàn),合理調(diào)節(jié)該參數(shù)可以將性能提升10%左右。

spark.shuffle.manager

** 默認(rèn)值**:sort
參數(shù)說明:該參數(shù)用于設(shè)置ShuffleManager的類型。Spark 1.5以后,有三個(gè)可選項(xiàng):hash、sort和tungsten-sort。HashShuffleManager是Spark 1.2以前的默認(rèn)選項(xiàng),但是Spark 1.2以及之后的版本默認(rèn)都是SortShuffleManager了。tungsten-sort與sort類似,但是使用了tungsten計(jì)劃中的堆外內(nèi)存管理機(jī)制,內(nèi)存使用效率更高。
調(diào)優(yōu)建議:由于SortShuffleManager默認(rèn)會對數(shù)據(jù)進(jìn)行排序,因此如果你的業(yè)務(wù)邏輯中需要該排序機(jī)制的話,則使用默認(rèn)的SortShuffleManager就可以;而如果你的業(yè)務(wù)邏輯不需要對數(shù)據(jù)進(jìn)行排序,那么建議參考后面的幾個(gè)參數(shù)調(diào)優(yōu),通過bypass機(jī)制或優(yōu)化的HashShuffleManager來避免排序操作,同時(shí)提供較好的磁盤讀寫性能。這里要注意的是,tungsten-sort要慎用,因?yàn)橹鞍l(fā)現(xiàn)了一些相應(yīng)的bug。

spark.shuffle.sort.bypassMergeThreshold

默認(rèn)值:200
參數(shù)說明:當(dāng)ShuffleManager為SortShuffleManager時(shí),如果shuffle read task的數(shù)量小于這個(gè)閾值(默認(rèn)是200),則shuffle write過程中不會進(jìn)行排序操作,而是直接按照未經(jīng)優(yōu)化的HashShuffleManager的方式去寫數(shù)據(jù),但是最后會將每個(gè)task產(chǎn)生的所有臨時(shí)磁盤文件都合并成一個(gè)文件,并會創(chuàng)建單獨(dú)的索引文件。
*調(diào)優(yōu)建議:當(dāng)你使用SortShuffleManager時(shí),如果的確不需要排序操作,那么建議將這個(gè)參數(shù)調(diào)大一些,大于shuffle read task的數(shù)量。那么此時(shí)就會自動啟用bypass機(jī)制,map-side就不會進(jìn)行排序了,減少了排序的性能開銷。但是這種方式下,依然會產(chǎn)生大量的磁盤文件,因此shuffle write性能有待提高。

spark.shuffle.consolidateFiles

默認(rèn)值:false
參數(shù)說明:如果使用HashShuffleManager,該參數(shù)有效。如果設(shè)置為true,那么就會開啟consolidate機(jī)制,會大幅度合并shuffle write的輸出文件,對于shuffle read task數(shù)量特別多的情況下,這種方法可以極大地減少磁盤IO開銷,提升性能。
調(diào)優(yōu)建議:如果的確不需要SortShuffleManager的排序機(jī)制,那么除了使用bypass機(jī)制,還可以嘗試將spark.shffle.manager參數(shù)手動指定為hash,使用HashShuffleManager,同時(shí)開啟consolidate機(jī)制。在實(shí)踐中嘗試過,發(fā)現(xiàn)其性能比開啟了bypass機(jī)制的SortShuffleManager要高出10%~30%。

spark.default.parallelism

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

num-executors

參數(shù)說明:該參數(shù)用于設(shè)置Spark作業(yè)總共要用多少個(gè)Executor進(jìn)程來執(zhí)行。Driver在向YARN集群管理器申請資源時(shí),YARN集群管理器會盡可能按照你的設(shè)置來在集群的各個(gè)工作節(jié)點(diǎn)上,啟動相應(yīng)數(shù)量的Executor進(jìn)程。這個(gè)參數(shù)非常之重要,如果不設(shè)置的話,默認(rèn)只會給你啟動少量的Executor進(jìn)程,此時(shí)你的Spark作業(yè)的運(yùn)行速度是非常慢的。
參數(shù)調(diào)優(yōu)建議:每個(gè)Spark作業(yè)的運(yùn)行一般設(shè)置機(jī)器個(gè)數(shù)量的Executor進(jìn)程比較合適,設(shè)置太少或太多的Executor進(jìn)程都不好。設(shè)置的太少,無法充分利用集群資源;設(shè)置的太多的話,大部分隊(duì)列可能無法給予充分的資源。

executor-memory

參數(shù)說明:該參數(shù)用于設(shè)置每個(gè)Executor進(jìn)程的內(nèi)存。Executor內(nèi)存的大小,很多時(shí)候直接決定了Spark作業(yè)的性能,而且跟常見的JVM OOM異常,也有直接的關(guān)聯(lián)。

參數(shù)調(diào)優(yōu)建議:每個(gè)Executor進(jìn)程的內(nèi)存設(shè)置4G8G較為合適。但是這只是一個(gè)參考值,具體的設(shè)置還是得根據(jù)不同部門的資源隊(duì)列來定。可以看看自己團(tuán)隊(duì)的資源隊(duì)列的最大內(nèi)存限制是多少,num-executors乘以executor-memory,就代表了你的Spark作業(yè)申請到的總內(nèi)存量(也就是所有Executor進(jìn)程的內(nèi)存總和),這個(gè)量是不能超過隊(duì)列的最大內(nèi)存量的。此外,如果你是跟團(tuán)隊(duì)里其他人共享這個(gè)資源隊(duì)列,那么申請的總內(nèi)存量最好不要超過資源隊(duì)列最大總內(nèi)存的1/31/2,避免你自己的Spark作業(yè)占用了隊(duì)列所有的資源,導(dǎo)致別的同學(xué)的作業(yè)無法運(yùn)行。

executor-cores

參數(shù)說明:該參數(shù)用于設(shè)置每個(gè)Executor進(jìn)程的CPU core數(shù)量。這個(gè)參數(shù)決定了每個(gè)Executor進(jìn)程并行執(zhí)行task線程的能力。因?yàn)槊總€(gè)CPU core同一時(shí)間只能執(zhí)行一個(gè)task線程,因此每個(gè)Executor進(jìn)程的CPU core數(shù)量越多,越能夠快速地執(zhí)行完分配給自己的所有task線程。

參數(shù)調(diào)優(yōu)建議:Executor的CPU core數(shù)量設(shè)置為2~4個(gè)較為合適。同樣得根據(jù)不同部門的資源隊(duì)列來定,可以看看自己的資源隊(duì)列的最大CPU core限制是多少,再依據(jù)設(shè)置的Executor數(shù)量,來決定每個(gè)Executor進(jìn)程可以分配到幾個(gè)CPU core。同樣建議,如果是跟他人共享這個(gè)隊(duì)列,那么num-executors * executor-cores不要超過隊(duì)列總CPU core的1/3~1/2左右比較合適,也是避免影響其他同學(xué)的作業(yè)運(yùn)行。

driver-memory

參數(shù)說明:該參數(shù)用于設(shè)置Driver進(jìn)程的內(nèi)存。

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

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容