一、CPU配置:
ApplicationMaster 虛擬 CPU內核
yarn.app.mapreduce.am.resource.cpu-vcores
ApplicationMaster占用的cpu內核數(Gateway--資源管理 )
//一般設置1個核,如果想啟動時候快一點可以多設置核數,但它不管資源分配,所以只要保證任務執行過程中不掛就可以了
容器虛擬 CPU內核
yarn.nodemanager.resource.cpu-vcores
//單 個NodeManager 最大能分配的cpu核數 (NodeManager --資源管理 )
因為所有該機器上的所有進程需要資源都向nodemanager申請資源,所以nodemanager設置為機器 最大能分配的核數,除非該機器上還有別的進程需要運行,且不是通過yarn進行資源調度。
結論:當前 nodemanager申請的 ApplicationMaster數總和小於nodemanager最大cpu內核數
Yarn 集群參數調優
二、內存配置:
container容器內存
yarn.nodemanager.resource.memory-mb
//單個NodeManager能分配的最大內存(NodeManager --資源管理)
//Memory Total = 單個NodeManager內存 * 節點數
結論:提交任務占用內存Memory Used小於Memory Total
Map 任務內存
mapreduce.map.memory.mb
//為作業的每個 Map 任務分配的物理內存量 (Gateway--資源管理 )
結論:map或reduce的內存需求不大於appmaster的內存需求
最大容器內存
yarn.scheduler.maximum-allocation-mb
//單個任務可申請最大內存 (ResourceManager--資源管理 )
Yarn 集群參數調優(以CDH集群為例)
三、同一個Map或者Reduce並行執行:
Map 任務推理執行(如果一個map任務執行特別慢,yarn會在其他機器上啟動一個一模一樣的map任務,yarn會看誰先執行完成,然后把其他一個任務關掉)
mapreduce.map.speculative //Gateway
Reduce 任務推理執行
mapreduce.reduce.speculative //Gateway
四、spark加日志查看(舊版本)
編輯 spark-defaults.conf
spark.yarn.historyServer.address=http://hostname:18088/
五、JVM重用
啟用 Ubertask優化:
mapreduce.job.ubertask.enable | (默認false) //true則表示啟用jvm重用(Gateway--性能 )
資源參數調優
了解完了Spark作業運行的基本原理之后,對資源相關的參數就容易理解了。所謂的Spark資源參數調優,其實主要就是對Spark運行過程中各個使用資源的地方,通過調節各種參數,來優化資源使用的效率,從而提升Spark作業的執行性能。以下參數就是Spark中主要的資源參數,每個參數都對應着作業運行原理中的某個部分,我們同時也給出了一個調優的參考值。
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,就代表了你的Spark作業申請到的總內存量(也就是所有Executor進程的內存總和),這個量是不能超過隊列的最大內存量的。此外,如果你是跟團隊里其他人共享這個資源隊列,那么申請的總內存量最好不要超過資源隊列最大總內存的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執行用戶代碼的內存不夠用,那么同樣建議調低這個參數的值。
資源參數的調優,沒有一個固定的值,需要同學們根據自己的實際情況(包括Spark作業中的shuffle操作數量、RDD持久化操作數量以及spark web ui中顯示的作業gc情況),同時參考本篇文章中給出的原理以及調優建議,合理地設置上述參數。
Executor的內存主要分為三塊:第一塊是讓task執行我們自己編寫的代碼時使用,默認是占Executor總內存的20%;第二塊是讓task通過shuffle過程拉取了上一個stage的task的輸出后,進行聚合等操作時使用,默認也是占Executor總內存的20%;第三塊是讓RDD持久化時使用,默認占Executor總內存的60%。
提交spark :
#!/bin/bash source /etc/profile export LANG=zh_CN.UTF-8 year=`date -d "yesterday" +%Y` month=`date -d "yesterday" +%m` day=`date -d "yesterday" +%d` SPARK_MASTER=spark://10.110.79.2:7077 SPARK_DEPLOY="--master yarn --deploy-mode cluster" #SPARK_RESOURCE="--executor-memory 45G --executor-cores 4" SPARK_RESOURCE="--num-executors 4" SCRIPT_PATH="/opt/shell/log" LOG_PATH="/app/log" cluster1="hdfs://logcluster2" jarname=/opt/shell/log/lib/leagsoft-1.0-SNAPSHOT-jar-with-dependencies.jar inputDir=/leagsoft outputMysqlDir=/model/leagsoft_user/mysql outputESDir=/model/leagsoft_user/es LOG_FILE="${LOG_PATH}/module/leagsoft/user/log_2hdfs_`date +%Y%m%d`" echo "#spark leagsoftUserInfo2hdfsAndES `date '+%Y-%m-%d %H:%M:%S'`" >> ${LOG_FILE} hadoop fs -test -e "${inputDir}/${year}/${month}/${day}" if [ $? -eq 0 ] ; then spark-submit ${SPARK_DEPLOY} ${SPARK_RESOURCE} \ --queue infrastructure \ --executor-memory 10G \ --executor-cores 2 \ --class com.express.sf.leagsoft.leagsoft_user \ --conf spark.default.parallelism=16 \ --conf spark.shuffle.consolidateFiles=true \ --conf "spark.es.nodes=10.110.77.48" \ --conf "spark.es.port=9200" \ --conf "spark.es.index.auto.create=true" \ --conf "spark.es.batch.size.entries=50000" \ --conf spark.kryoserializer.buffer.max=64mb \ --conf spark.kryoserializer.buffer=256 \ "${jarname}" \ ${cluster1}${inputDir}/$year/$month/$day ${cluster1}${outputESDir}/$year/$month/$day ${cluster1}${outputMysqlDir}/$year/$month/$day ret=$? fi echo "#結束 `date '+%Y-%m-%d %H:%M:%S'`" >> ${LOG_FILE} exit $ret
注意,有些參數是和運行模式有關系的,比如 total-executor-cores 只對standalone和Mesos模式起作用,對cluster模式不起作用
參數解釋
--queue infrastructure \
提交到yarn 上使用的資源隊列,默認是default,這里使用infrastructure ,資源對列在hadoop中設置,詳見http://blog.csdn.net/cottonduke/article/details/60576545
---------------------
作者:YiRan_Zhao
來源:CSDN
原文:https://blog.csdn.net/yiran_zhao/article/details/81089248
版權聲明:本文為博主原創文章,轉載請附上博文鏈接!