007.hive上亿级别的表关联 调优

环境:公司决定使用宽表,将10个相关的大表进行全量关联 程序员

(1个上亿级别的表,5个上千万的表,剩下的表都不到百万的表) sql


花了两天的时间研究,测试 apache

例如: 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。 oop


也多人会说,你傻逼呀,设置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个reduces
set 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) spa

2. hive.exec.reducers.max(默认为999) code

计算reducer数的公式很简单:

N=min(参数2,总输入数据量/参数1)


而后查询得知:

reduce为1,是由于:

  1. 没有使用group by

  2. 使用了order by

  3. 笛卡尔积

我TM都使了一遍,仍是reduce=1,我当时很无语,就尼玛不能再作清楚一点吗?(我但是小白呀!!!)


时间:3个小时都没跑完,一直都是83%


因此hadoop,看到了这个语句,就会分配一个reduce


如何欺骗hive分配reduce呢?

而后修改脚本(固然上面的 设置reduce数 这个不能少噢)

# 如何欺骗hive多分配reduce
select 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


  1. 使用聚合函数,加 group by

  2. 而后小表放在前面(有人说:我TM要全部的信息,那你就用全链接呗)

  3. 而后大表通常就日后排,从小到大,一顺排下来就行

这样就能欺骗hive分配多个reduce,达到调优的效果


时间:15分钟不到,兴奋到高潮了吗?哈哈


缺点:

  1. 生成200个文件,比较麻烦

  2. 设置并行,对性能要求有点高,因此适度设置并行数量就行


并行参数,仅作参考

当参数为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



过高兴了,做为一个程序员,要求不高:电脑高配,作的事情有挑战,而且花几天时间能调通,就知足勒

乐于分享交流,但愿能帮到像我同样遇到此困难的人,呵呵

it技术的进步,不就是这样相互交流共享学习吗?

呵呵,那么。。。你作到吗?

相关文章
相关标签/搜索