一、hive作业中map个数
1.通常情况下,作业会通过input的目录产生一个或多个map任务
决定因素:input的文件总个数,input的文件大小,集群设置的文件块大小(目前为128M,可在hive中通过set dfs.block.size;命令查看设置参数,该参数不能自定义修改);
2.释疑:当文件小于128M,一个文件会生成一个maptask,当文件超过128M,会进行切分。
3.map个数越多越好?
如果一个任务有很多小文件(远远小于块大小128m),则每个小文件也会被当做一个块,生成对应map任务来完成,而一个map任务启动和初始化的时间远远大于逻辑处理的时间,就会造成很大的资源浪费。而且,同时可执行的map数是受限的。
4.每个map处理接近128m的文件块是不是最合适的?
假如有一个127m的文件,正常会用一个map去完成,但这个文件只有一个或者两个小字段,却有几千万的记录,如果map处理的逻辑比较复杂,用一个map任务去做,也会比较耗时。
- 可以合理调整以下参数可以达到控制map数目的:
set mapred.max.split.size=100000000;
set mapred.min.split.size.per.node=100000000;
set mapred.min.split.size.per.rack=100000000;
set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;
- 重建目标表将物理分区切分成多份,如下:
insert overwrite table cs_test01 partition(dt) as
select * from emp distribute by cast(rand() * 10 as int);
注意:distribute by会将数据随机的分到10个reduce中,保证每个reduce处理的数据量大体一致;每个分区目录下面会形成10个文件;
Hive Distribute by 应用之动态分区小文件过多问题优化_javastart的博客-CSDN博客_由于动态分区导致生成临时文件过多
二、调整hive作业中的reduce任务个数
1、调整reduce任务个数方法一:
设置参数:
set hive.exec.reducers.bytes.per.reducer=1000000000;
set hive.exec.reducers.max=999;
2、设置reduce任务个数方法二:
调整参数:
set mapred.reduce.tasks=10;
三、hive合并输入输出文件
如果Hive的输入文件是大量的小文件,而每个文件启动一个map的话是对yarn资源的浪费,同样的,hive输出的文件也远远小于HDFS块大小,对后续处理也是不利的。
HIVE中支持通过参数调整输入和输出的文件大小
1、合并输入文件
set mapred.max.split.size=256000000; #每个Map最大输入大小
set mapred.min.split.size.per.node=100000000; #一个节点上split的至少的大小
set mapred.min.split.size.per.rack=100000000; #一个交换机下split的至少的大小
set hive.input.format=org.apache.Hadoop.hive.ql.io.CombineHiveInputFormat; #执行Map前进行小文件合并
开启org.apache.hadoop.hive.ql.io.CombineHiveInputFormat后,一个data node节点上多个小文件会进行合并,合并文件数由mapred.max.split.size限制的大小决定,mapred.min.split.size.per.node决定了多个data node上的文件是否需要合并,mapred.min.split.size.per.rack决定了多个交换机上的文件是否需要合并。
2、合并输出文件
set hive.merge.mapfiles = true #在Map-only的任务结束时合并小文件
set hive.merge.mapredfiles = true #在Map-Reduce的任务结束时合并小文件
set hive.merge.size.per.task = 256*1000*1000 #合并文件的大小
set hive.merge.smallfiles.avgsize=16000000 #当输出文件的平均大小小于该值时,启动一个独立的map-reduce任务进行文件merge。
以上参数在hive-0.13.1中默认值如下:
hive (default)> set hive.merge.mapfiles;
hive.merge.mapfiles=true
hive (default)> set hive.merge.mapredfiles;
hive.merge.mapredfiles=false
hive (default)> set hive.merge.size.per.task;
hive.merge.size.per.task=256000000
hive (default)> set hive.merge.smallfiles.avgsize;
hive.merge.smallfiles.avgsize=16000000
综上所述:一个可能的hive 作业可以设置为以下格式:
set mapred.max.split.size=100000000;
set mapred.min.split.size.per.node=100000000;
set mapred.min.split.size.per.rack=100000000;
set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;
set hive.exec.reducers.bytes.per.reducer=1000000000;
set hive.exec.reducers.max=256;
set hive.merge.mapfiles=true;
set hive.merge.mapredfiles =ture;
set hive.merge.size.per.task=256000000;
set hive.merge.smallfiles.avgsize=16000000;
select deptno,count(1) from emp group by deptno;
或者
set mapred.max.split.size=100000000;
set mapred.min.split.size.per.node=100000000;
set mapred.min.split.size.per.rack=100000000;
set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;
set mapred.reduce.tasks=10;
set hive.merge.mapfiles=true;
set hive.merge.mapredfiles =ture;
set hive.merge.size.per.task=256000000;
set hive.merge.smallfiles.avgsize=16000000;
select deptno,count(1) from emp group by deptno;
附录:hive优化之调整mapreduce数目 - ChavinKing - 博客园hive优化之调整mapreduce数目 - ChavinKing - 博客园