hive上亿级别的表关联如何调优
这篇文章主要介绍了hive上亿级别的表关联如何调优,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。
环境:公司决定使用宽表,将10个相关的大表进行全量关联
(1个上亿级别的表,5个上千万的表,剩下的表都不到百万的表)
花了两天的时间研究,测试
例如: a~g这几个表中,a表为上亿级别的表,5个上千万的表,剩下为表都百万的表
select a.uesrid,b.citycode,b.register_num, ... ,g.active_num from(select userid,citycode from a)left outer join(select userid,register_num from b)on (a.userid=b.userid)...left outer join(select userid,active_num from g)on (a.userid=b.userid)
你会发现
最后一个job异常慢,并且reduce为1。
也多人会说,你傻逼呀,设置reduce数呀,对这是一个好办法,但是结果如何呢?
#设置传输格式set mapred.output.compress=true; set hive.exec.compress.output=true;set mapred.output.compression.codec=org.apache.hadoop.io.compress.GzipCodec;set io.compression.codecs=org.apache.hadoop.io.compress.GzipCodec;#设置200个reducesset mapred.reduce.tasks=200; #设置并行(甚至还。。。设置并行) set hive.exec.parallel=true;set hive.exec.parallel.thread.number=16; //同一个sql允许最大并行度,默认为8
草,我就是按照网上各种教程,测试了一整天,还是最后一个reduce为1;(我可是上亿级别噢!!!)
hive自动分配reduce的计算方法
1. hive.exec.reducers.bytes.per.reducer(默认为1000^3)
2. hive.exec.reducers.max(默认为999)
计算reducer数的公式很简单:
N=min(参数2,总输入数据量/参数1)
然后查询得知:
reduce为1,是因为:
没有使用group by
使用了order by
笛卡尔积
我TM都使了一遍,还是reduce=1,我当时很无语,就尼玛不能再做清楚一点吗?(我可是小白呀!!!)
时间:3个小时都没跑完,一直都是83%
所以hadoop,看到了这个语句,就会分配一个reduce
如何欺骗hive分配reduce呢?
然后修改脚本(当然上面的 设置reduce数 这个不能少噢)
# 如何欺骗hive多分配reduceselect a.uesrid,b.citycode,sum(b.register_num), ... ,sum(g.active_num) # 求聚合函数from(select userid,citycode from x) # x,y表示这几个表中最小的一个表full outer join(select userid,unregister from y) # x,y表示这几个表中最小的一个表on (x.userid=y.userid) # (可交替的设置 y.userid=b.userid)full outer join (select userid,register_num from b)on (x.userid=b.userid) # 关联条件,都用小表进行关联...right outer join(select userid,active_num from a) # 最大的表放在最后on (y.userid=a.userid) # (可交替的设置 y.userid=b.userid)group by a.userid,b.citycode; # 最后进行group by
使用聚合函数,加 group by
然后小表放在前面(有人说:我TM要所有的信息,那你就用全连接呗)
然后大表一般就往后排,从小到大,一顺排下来就行
这样就能欺骗hive分配多个reduce,达到调优的效果
时间:15分钟不到,兴奋到高潮了吗?哈哈
缺点:
生成200个文件,比较麻烦
设置并行,对性能要求有点高,所以适度设置并行数量就行
并行参数,仅做参考
当参数为false的时候,三个job是顺序的执行
set hive.exec.parallel=false;
但是可以看出来其实两个子查询中的sql并无关系,可以并行的跑
set hive.exec.parallel=true;
hive> set hive.exec.parallel.thread.number; (如果机器一般,可以并行设置3,感觉比较合理)
hive.exec.parallel.thread.number=8 默认并行数为8
感谢你能够认真阅读完这篇文章,希望小编分享的"hive上亿级别的表关联如何调优"这篇文章对大家有帮助,同时也希望大家多多支持,关注行业资讯频道,更多相关知识等着你来学习!