1、合并小文件
hive.merge.mapfile=true;
在Map-only的任务结束时合并小文件。
是否开启合并 Map 小文件,对于 Hadoop 0.20 以前的版本,起一个新的 Map/Reduce Job,对于 0.20 以后的版本,则是起使用 CombineInputFormat 的 MapOnly Job。
是否开启合并 Map 端小文件,当Hive输入由很多个小文件组成,由于每个小文件都会启动一个map任务,如果文件过小,会使得map任务启动和初始化的时间大于逻辑处理的时间,造成资源浪费,甚至OOM。为此,当我们启动一个任务,发现输入数据量小但任务数量多时,需要注意在Map前端进行输入合并。当然,在我们向一个表写数据时,也需要注意输出文件大小
默认值:true
hive.merge.mapredfile=true;
是否开启合并 Map/Reduce 小文件,对于 Hadoop 0.20 以前的版本,起一个新的 Map/Reduce Job,对于 0.20 以后的版本,则是起使用 CombineInputFormat 的 MapOnly Job。
是否开启合并 Map/Reduce 小文件,即是否在Map-Reduce的任务结束时合并小文件。
默认值:false
hive.merge.size.per.task=32000000; //自定
每个任务合并后文件的大小,根据此大小确定 reducer 的个数,默认 256 M。
默认值:256000000
hive.merge.smallfiles.avgsize=16000000; //自定
需要合并的小文件群的平均大小,默认 16 M。
默认值:16000000
2、动态分区
hive.mapred.mode=nonstrict;
Map/Redure 模式,如果设置为 strict,将禁止3中类型的查询:
1.分区表的where筛选条件必须含有分区字段;
2.对使用了order by语句的查询,必须使用limit语句(order by语句为执行排序会将所有的结果集数据分发到同一个reducer中进行处理,增加limit语句可以防止reducer额外执行很长时间)
3.限制笛卡儿积的查询,就是有where语句,而没有on语句。
默认值: ‘nonstrict’
hive.exec.dynamic.partition.mode=nonstrict;
打开动态分区后,动态分区的模式,有 strict 和 nonstrict 两个值可选,strict 要求至少包含一个静态分区列,nonstrict 则无此要求。
默认值:strict
hive.exec.max.dynamic.partitions.pernode=10000;[自定,默认100]
单个 reduce 结点所允许的最大的动态分区的个数。
默认值:100
3、groupby导致数据倾斜
目前发现需要进行优化的较多出现在出现join、distinct的情况下,而且一般都是reduce过程较慢。
Reduce过程比较慢的现象又可以分为两类:
1)情形一:map已经达到100%,而reduce阶段一直是99%,属于数据倾斜
2)情形二:使用了count(distinct)或者group by的操作,现象是reduce有进度但是进度缓慢,31%-32%-34%…一个附带的提示是使用reduce个数很可能是1。
问题产生的RC是需要在大数据集下做多个字段的distinct,而且还是多个字段,所以最先需要设置set hive.groupby.skewindata=true
利用2次MRjob进行负载均衡
hive.groupby.skewindata=true;
决定 group by 操作是否支持倾斜的数据。
默认值:false
hive.auto.convert.join=true; 自动mapjoin,
是否根据输入小表的大小,自动将 Reduce 端的 Common Join 转化为 Map Join,从而加快大表关联小表的 Join 速度。
默认值:false
4、join导致数据倾斜
set hive.optimize.skewjoin=true; --如果是join 过程出现倾斜 应该设置为true
5、对reduce个数限定
mapred.reduce.tasks=-1;
所提交 Job 的 reduer 的个数,使用 Hadoop Client 的配置。
默认值:1
[默认不限制]【hive脚本中不起作用,MR中起作用】
hive.exec.reduces.bytes.per.reducer=1000000000L;
每一个 reducer 的平均负载字节数。
默认值:1000000000
hive.exec.reducers.max=999;[默认]
设置reducer 个数的上限。
可以阻止某个查询消耗过多的reducer资源,对这个属性值大小的设定,一个建议的计算公式如下:
(集群总Reduce槽位个数*1.5) / (执行中查询的平均个数)
1.5倍数是一个经验系数,用于防止未充分利用集群的情况。
默认值:999
二、生产环境中的场景
1、实际中只有map不起reduce的任务
hive中在做查询时,经常会碰到这种问题,任务只起map不起reduce;
环境:
hive
100出头的节点
7T左右的内存
basic表有300-400个分区,总数据量在6亿-7亿;
如下sql:
select * from basic_sum where user_log_acct=‘abcd’;
这个sql只会起一个job,这个job只有map,没有reduce;输入数据较多,会比较慢;
可以对表进行distribute by,强制让其产生reduce;
优化后sql如下:
select * from basic_sum where user_log_acct=‘abcd’ distribute by rand(1234);
这个sql会产生reduce;