合理設置隊列名
mapreduce.job.queuename
設置隊列名
map讀取時進行小文件整合html
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,那麼就設置成
java
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的一些經常使用設置
node
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這個文件便可apache
steven liu數組