1、fetch抓取(可配置,默认开启)
简单的select筛选查询不启动mapreduce。。直接查
2、小表与大表关联
使用map join(默认开启),每个map task把小表数据全部下载到内存中,然后与大表分片数据进行关联。。避免在reducer端关联造成数据倾斜。
3、大表与大表关联
(1)空key处理:
《1》当空key对应的行数据都是异常垃圾数据,那么在关联是先使用子查询过滤掉空key。。
《2》当空key对应的行数据是有用的,需要查询出来。。那么可以用case when把空key转换为随机数据,随机数据在不会与其他表的字段产生关联,此时这些空key数据会被随机分配到不同的reducer,避免集中在同一个reducer中产生数据倾斜问题。并且这些数据本来就是不产生关联的,所以不会影响原有逻辑
(2)表与表之间的某个字段关联之后可能会产生比较大的数据:两张表都分桶。。
https://blog.csdn.net/qq_36951116/article/details/102960149
4、group by
导致原因:group by分组的数据量多了也会出现数据倾斜问题,即某些分组的数据量很大,然后都集中在某些个reducer上。。
解决:
(1)、启用map端部分聚合
set hive.map.aggr = true
(2)、在 Map 端进行聚合操作的条目数目
set hive.groupby.mapaggr.checkinterval = 100000
(3)、负载均衡
set hive.groupby.skewindata = true
第一个 MR Job 中,Map 的输出结果会随机分布到 Reduce 中,每个 Reduce 做部分聚合操作,并输出结果,这样处理的结
果是相同的 Group By Key 有可能被分发到不同的 Reduce 中,从而达到负载均衡的目的;
第二个 MR Job 再根据预处理的数据结果按照 Group By Key 分布到 Reduce 中(这个过程可以保证相同的 Group By Key 被分布到同一个 Reduce 中),最后完成最终的聚合操作。
5、Count(Distinct) 去重统计
原因:这种查询不论指定了多少reducer,hive都只会启动一个reducer。。导致一个reducer数据量太大,内存占用高。
解决:在子查询中先去重,然后再count子查询的结果
6、筛选条件尽量在子查询中做完,然后再进行关联
7、在集群空闲时,可以使用并行执行加快任务处理速度。。当然,得是在系统资源比较空闲的时候才有优势,否则,没资源,并行也起不来。
set hive.exec.parallel=true; //打开任务并行执行
set hive.exec.parallel.thread.number=16; //同一个 sql 允许最大并行度,默认为 8。
8、jvm重用
JVM重用可以使得JVM实例在同一个 job 中重新使用N次。
开启 JVM 重用将一直占用使用到的 task 插槽,以便进行重用,直到任务完成后才能释放。
如果某个“不平衡的”job 中有某几个 reduce task 执行的时间要比其他 Reduce task 消耗的时间多的多的话,那么保留的插槽就会一直空闲着却无法被其他的 job使用,直到所有的 task 都结束了才会释放。
9、推测执行
当有些任务的运行速度可能明显慢于其他任务,hadoop会为这些拖后腿的任务启动一个备份的任务,执行相同的操作,最终选用最先成功运行完成任务的计算结果作为最终结果。
在hadoop的mapred-site.xml文件配置mapreduce.map.speculative和mapreduce.reduce.speculative为true(默认就是true)。
或者在hive中配置hive.mapred.reduce.tasks.speculative.execution为true(默认为true)