group by 数据倾斜:
方案一:开启map短聚合hive.map.aggr=true;
方案二:实现随机分区。
实现随机分区
select * from table distribute by rand();
方案三:数据倾斜时自动负载均衡。
hive.groupby.skewindata=true;
#开启该参数以后,当前程序会自动通过两个MapReduce来运行
#第一个MapReduce自动进行随机分布到Reducer中,每个Reducer做部分聚合操作,输出结果
#第二个MapReduce将上一步聚合的结果再按照业务(group by key)进行处理,保证相同的分布到一起,最终聚合得到结果
join数据倾斜:
方案一:提前过滤,将大数据变为小数据,实现map join。
方案二:使用bucket join。
方案三:使用skew join。
#将Map Join和Reduce Join进行合并,如果某个值出现了数据倾斜,就会将产生数据倾斜的数据单独使用Map Join来实现
#其他没有产生数据倾斜的数据由Reduce Join来实现,这样就避免了Reduce Join中产生数据倾斜的问题
#最终将Map Join的结果和Reduce Join的结果进行Union合并
#开启运行过程中skewjoin
set hive.optimize.skewjoin=true;
#如果这个key的出现的次数超过这个范围
set hive.skewjoin.key=100000;
#在编译时判断是否会产生数据倾斜
set hive.optimize.skewjoin.compiletime=true;
set hive.optimize.union.remove=true;
#如果Hive的底层走的是MapReduce,必须开启这个属性,才能实现不合并
set mapreduce.input.fileinputformat.input.dir.recursive=true;
maptask个数,在hive中,调整maptask的个数直接去HDFS调整文件的大小和个数,效率较高。
reducetask个数,用过代码指定,job.setNumReduceTask(N),在hive中reducetask的个数受一下几个条件的控制。
(1)每个 Reduce 处理的数据量默认是 256MB
hive.exec.reducers.bytes.per.reducer=256000000
(2)每个任务最大的 reduce 数,默认为 1009
hive.exec.reducsers.max=1009
(3)mapreduce.job.reduces
该值默认为-1,由 hive 自己根据任务情况进行判断。
--如果用户用户不设置 hive将会根据数据量或者sql需求自己评估reducetask个数。
--用户可以自己通过参数设置reducetask的个数
set mapreduce.job.reduces = N
--用户设置的不一定生效,如果用户设置的和sql执行逻辑有冲突,比如order by,在sql编译期间,hive又会将reducetask设置为合理的个数。
Number of reduce tasks determined at compile time: 1