合理设置队列名
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数组