yarn一些最佳配置


合理設置隊列名

mapreduce.job.queuename
設置隊列名
map讀取時進行小文件整合

    mapreduce.input.fileinputformat.split.minsize
    mapreduce.input.fileinputformat.split.maxsize
    mapreduce.input.fileinputformat.split.minsize.per.node
    mapreduce.input.fileinputformat.split.minsize.per.rack

mapreduce中map的個數和兩個有關,一個是文件的個數,一個是大小,默認split是128M, 如果一個文件大於128M,例如129M,那么會有兩個map,一個是128M,一個是1M。
又例如有10個文件,每個都是1M,那么map是會有10個的。
對於這種小文件太多,或者是我們想講每一個map處理的數據量大一些,就應該設置上面的幾個參數,上面幾個參數是byte的單位。
例如我們想設置一次處理1G,那么就設置成

mapreduce.input.fileinputformat.split.minsize = 1024*1024*1024
mapreduce.input.fileinputformat.split.maxsize = 1024*1024*1024
mapreduce.input.fileinputformat.split.minsize.per.node = 1024*1024*1024
mapreduce.input.fileinputformat.split.minsize.per.rack = 1024*1024*1024


值得注意的是,conf中最好設置一個如下參數,mapreduce默認的mapreduce.job.max.split.locations為10個,意味着如果一個map處理的split的文件超過了10個節點,那么就會有數據截取,導致程序報錯

conf.setInt("mapreduce.job.max.split.locations", 1000);


推測功能

mapreduce.reduce.speculative
默認是true,有時候需要設置成false。
參考: http://itfish.net/article/60389.html或者搜索
container大小設置最佳實踐

mapreduce.map.memory.mb 和 mapreduce.reduce.memory.mb 和mapreduce.map.cpu.vcores和 mapreduce.reduce.cpu.vcores

mapreduce.map.memory.mb 默認1024M,一個map啟動的container是1024M
mapreduce.reduce.memory.mb 默認3072M,一個map啟動的container是3072
mapreduce.map.cpu.vcores默認1個vcore,一個map任務默認使用一個虛擬核運行
mapreduce.reduce.cpu.vcores默認1個vcore,一個reduce任務默認使用一個虛擬核運行。

調優就是盡可能的讓集群資源充分利用,這里需要根據具體的需求和集群資源情況來定。
例如不考慮內存溢出等情況, 集群資源如下
Memory Total     VCores Total
320G     80

如果數據比較均勻,應該盡可能的設置成如下:
mapreduce.map.memory.mb     mapreduce.reduce.memory.mb     mapreduce.map.cpu.vcores     mapreduce.reduce.cpu.vcores
4096     4096     1     1

這樣並發數能到

max(320G/4G,80vcore/1vcore)=80
上面是map核reduce都到了最大的80的並發,集群利用最充分。

一般來說,我們默認mapreduce.map.cpu.vcores和mapreduce.reduce.cpu.vcores為1個就好了,但是對於一個map和一個reduce的container的內存大小設置成了4G,如果一個map和一個reduce處理的任務很小,那又會很浪費資源,這時,對於map來說,可以用前面說的小文件整合,設置mapreduce.input.fileinputformat.split來解決map的大小,盡可能接近4G,但是又要注意可能出現的內存溢出的情況。
對於reduce,1個container啟動用了4G內存,那這4G內存也應盡可能的充分使用,這時候,我們盡量的評估進入到reduce的數據大小有多少,合理的設置reduceTask數,這一步是比較麻煩的,因為這里如果出現數據傾斜將會導致oom內存溢出錯誤。

前面說到了,並發數受到集群總內存/container的限制,同時,並發數也會受到集群vcore的限制,還是上面那個例子,例如集群資源為320G,80vcore,我一個map任務為2G,由於受到cpu的限制,最多同時80個vcore的限制,那么內存使用只能使用160G。這顯然是浪費資源了。

對於mapreduce.map.cpu.vcores和mapreduce.reduce.cpu.vcores,為什么默認是1呢,在集群的內存/cpu很小的情況下,能否一個map端將這兩個值設置成2或者更大呢。這是當然可以的,但是,即使我們將這個設置成2,任務的並發並不會是 Vcores Total/2的關系,並發仍然將是上面兩條決定的。舉個例子,還是320G,80vcore集群。我們設置mapreduce.map.memory.mb為4G,mapreduce.map.cpu.vcores為2, 很多人以為我一個map需要兩個核,那么80vcore/2vcore=40,那么我們並發最大只能用到40*4=160G的內存,其實這是錯誤的,這種情況,我們任然基本上能將內存占滿,並發數任然能到80個。這個時候, mapreduce.map.cpu.vcores基本就失效了。后來仔細想了想,一個map或者reduce任務,里面的數據應該並不可能會有多線程並發,但是mapreduce.map.cpu.vcores為什么會有這個參數呢,后來想了一下,一個map或者reduce任務,代碼的執行肯定是一個線程,但是任務的狀態等監控,垃圾回收等,是可以使用另外一個線程來運行的,這也是將mapreduce.map.cpu.vcores設置成2可能會快一點的效果。
我曾經碰到一個cpu十分充足的集群,vcore和內存比例是1比1,但是為了讓數據不傾斜,我們的mapreduce.reduce.memory.mb至少要到4G,那么這時候,其實cpu就只能利用1/4了,這時候cpu很充足,我便嘗試將mapreduce.map.cpu.vcores設置成2.其實這樣也並不是說我一定每個map都能使用到2個vcore,只不過有時候,有的任務狀態監控,jvm垃圾回收等,就有了另外一個vcore來運行了。

mapreduce.map.cpu.vcores補充20180914, 這個參數貌似在公平隊列是沒用的,vCores用於較大的群集,以限制不同用戶或應用程序的CPU。如果您自己使用YARN,則沒有理由限制容器CPU。這就是為什么在Hadoop中默認甚至不考慮vCore的原因,capacity-schedule調度下才有用,之前對這個參數不了解,后來在StackOverflow提了一個問題才明白
https://stackoverflow.com/questions/51276027/whats-the-function-of-mapreduce-map-cpu-vcores
mapreduce.task.io.sort.mb

這個參數理解需要理解mapreduce的shuffle過程,mapreduce的shuffle中,有一個環形緩沖區(就是一個帶有前后兩個指針的數組,shuffle過程自行搜索),這個值默認是100兆,配合上有個參數mapreduce.task.io.sort.spill.percent,一般這個參數默認為0.8,那么就意味着,這個數組到了80M,我就要開始進行排序了,然后要往磁盤寫數據了。所以這個值越大,就不用導致頻繁的溢出了。
按照經驗,一般這個值和map的輸出,reduce的輸入的大小相關比較好,但是這個值最好別超過2046,假如一個reduce處理的數據量為1G,那么這個值可以設置成200M, 一般的經驗是reduce處理的數據量/5的關系比較好。
mapreduce.map.java.opts

就是一個map container中jvm虛擬機的內存
一般設置成mapreduce.map.memory.mb的0.8倍比較合適
例如mapreduce.map.memory.mb=4096
mapreduce.map.java.opts 設置成 -Xmx3276M
mapreduce.reduce.java.opts

就是一個reduce container中jvm虛擬機的內存
一般設置成mapreduce.reduce.memory.mb的0.8倍比較合適
例如mapreduce.reduce.memory.mb=4096
mapreduce.reduce.java.opts 設置成 -Xmx3276M
yarn.app.mapreduce.am.resource.mb

MR ApplicationMaster占用的內存量,具體設置TODO,記得有時候小文件太多,超過多少萬,這個太小了任務不會運行
mapreduce.task.timeout

mapreduce任務默認超時時間,有時候搶隊列的時候,這個會用上,默認值600000就好,不用管
mapred.max.map.failures.percent

允許map失敗的比例,默認是0,可以根據自己需求,合理設置
mapred.max.reduce.failures.percent

允許reduce失敗的比例,默認是0,可以根據自己需求,合理設置
mapreduce.job.reduce.slowstart.completedmaps

map不用跑完就可以開始reduce了的比例,默認是0.95(網上說的0.05感覺不對啊),也就是map完成到百分之95時就可以開始reduce了,這樣的好處是到了map最后幾個,其實大多數資源都空閑了,這時候就先進行reduce吧,不然等全部跑完map有點浪費資源了。
但是我之前碰到過一次資源死鎖餓死的情況,就是map還有幾個沒跑完,reduce已經起來了,然而reduce需要等待map跑完的數據,reduce端拉不到,然后map端也沒完成,並且整個集群的資源都被利用完了,這樣map跑不完,reduce也跑不完,就這樣相互等待卡着
HADOOP_CLIENT_OPTS

hadoop jar啟動的時候,client端的jvm內存大小,太小會有問題,舉個例子。太小的話,如果跑的文件個數比較多,JOB還未起來就會報OOM錯誤

hadoop-oom

此配置在hadoop-env.sh中

export HADOOP_CLIENT_OPTS="-Xmx1024m" 


擴展 HIVE的一些常用設置

set mapreduce.job.queuename=default
set yarn.nodemanager.vmem-pmem-ratio=4.2;
set mapreduce.map.memory.mb=16384;
set mapred.map.java.opts = -Xmx13106M;
set mapred.map.child.java.opts=-Xmx13106M;
set hive.merge.mapredfiles=true;

set hive.exec.reducers.max=150;
set mapreduce.reduce.memory.mb=30240;
set mapreduce.reduce.java.opts= -Xmx24192m;
set mapreduce.task.io.sort.mb=1024;

set mapred.max.split.size=8036870912;
set mapred.min.split.size.per.node=1234217728;
set mapred.min.split.size.per.rack=1234217728;
set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;

我一般將這些設置放在一個目錄下,保存為.hql文件,然后source這個文件即可

steven liu


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM