一起学Hive——总结常用的Hive优化技巧 (2)

如果我们将数量由5改成15。还是执行select user_id,count(1) as cnt
from orders group by user_id limit 20;SQL,在控制台打印的信息是:

Launching Job 1 out of 1 Number of reduce tasks not specified. Defaulting to jobconf value of: 15 In order to change the average load for a reducer (in bytes): set hive.exec.reducers.bytes.per.reducer=<number> In order to limit the maximum number of reducers: set hive.exec.reducers.max=<number> In order to set a constant number of reducers: set mapreduce.job.reduces=<number> Starting Job = job_1538917788450_0027, Tracking URL = :8088/proxy/application_1538917788450_0027/ Kill Command = /usr/local/src/hadoop-2.6.1/bin/hadoop job -kill job_1538917788450_0027 Hadoop job information for Stage-1: number of mappers: 1; number of reducers: 15

可见reducer的数量已经由5变为15个。

小结,控制hive中reducer的数量由三种方式,分别是:

set hive.exec.reducers.bytes.per.reducer=<number> set hive.exec.reducers.max=<number> set mapreduce.job.reduces=<number>

其中set mapreduce.job.reduces=的方式优先级最高,set hive.exec.reducers.max=优先级次之,set hive.exec.reducers.bytes.per.reducer= 优先级最低。从hive0.14开始,一个reducer处理文件的大小的默认值是256M。

reducer的数量并不是越多越好,我们知道有多少个reducer就会生成多少个文件,小文件过多在hdfs中就会占用大量的空间,造成资源的浪费。如果reducer数量过小,导致某个reducer处理大量的数据(数据倾斜就会出现这样的现象),没有利用hadoop的分而治之功能,甚至会产生OOM内存溢出的错误。使用多少个reducer处理数据和业务场景相关,不同的业务场景处理的办法不同。

技巧2.使用Map join

sql中涉及到多张表的join,当有一张表的大小小于1G时,使用Map Join可以明显的提高SQL的效率。如果最小的表大于1G,使用Map Join会出现OOM的错误。
用法:

select /*+ MAPJOIN(table_a)*/,a.*,b.* from table_a a join table_b b on a.id = b.id 技巧3.使用distinct + union all代替union

如果遇到要使用union去重的场景,使用distinct + union all比使用union的效果好。
distinct + union all的用法:

select count(distinct *) from ( select order_id,user_id,order_type from orders where order_type='0' union all select order_id,user_id,order_type from orders where order_type='1' union all select order_id,user_id,order_type from orders where order_type='1' )a;

union的用法:

select count(*) from( select order_id,user_id,order_type from orders where order_type='0' union select order_id,user_id,order_type from orders where order_type='0' union select order_id,user_id,order_type from orders where order_type='1')t; 技巧4.解决数据倾斜的通用办法

数据倾斜的现象:任务进度长时间维持在99%,只有少量reducer任务完成,未完成任务数据读写量非常大,超过10G。在聚合操作是经常发生。
通用解决方法:set hive.groupby.skewindata=true;
将一个map reduce拆分成两个map reduce。

说说我遇到过的一个场景,需用统计某个一天每个用户的访问量,SQL如下:

select t.user_id,count(*) from user_log t group by t.user_id

执行这条语句之后,发现任务维持在99%达到一个小时。后面自己分析user_log表,发现user_id有很多数据为null。user_id为null的数据会有一个reducer来处理,导致出现数据倾斜的现象。解决方法有两种:
1、通过where条件过滤掉user_id为null的记录。
2、将为null的user_id设置一个随机数值。保证所有数据平均的分配到所有的reducer中处理。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zzsjwf.html