更多内容,欢迎观众公众号:livandata
1、group by的计算原理:
代码为:SELECT uid, SUM(COUNT) FROM logs GROUP BY uid;
可以看到,group by本身不是全局变量,任务会被分到各个map中进行分组,然后再在reduce中聚合。
默认设置了hive.map.aggr=true,所以会在mapper端先group by一次,最后再把结果merge起来,为了减少reducer处理的数据量。注意看explain的mode是不一样的。mapper是hash,reducer是mergepartial。如果把hive.map.aggr=false,那将groupby放到reducer才做,他的mode是complete。
优化点:
Group by主要是面对数据倾斜的问题。
很多聚合操作可以现在map端进行,最后在Reduce端完成结果输出。
Set hive.map.aggr = true 是否在Map端进行聚合,默认为true;
Set hive.groupby.mapaggr.checkinterval=1000000 在Map端进行聚合操作的条目数目;
当使用Groupby有数据倾斜的时候进行负载均衡:
Set hive.groupby.skewindata=true;hive自动进行负载均衡;
策略就是把MR任务拆分成两个MR Job:第一个先做预汇总,第二个再做最终汇总;
第一个Job:
Map输出结果集中缓存到maptask中,每个Reduce做部分聚合操作,并输出结果,这样处理的结果是相同Group by Key有可能被分到不同的reduce中,从而达到负载均衡的目的;
第二个Job:
根据第一阶段处理的数据结果按照group by key分布到reduce中,保证相同的group by key分布到同一个reduce中,最后完成最终的聚合操作。
2、join的计算原理:
代码为:SELECT a.id,a.dept,b.age FROM a join b ON (a.id = b.id);
1)Map阶段:
读取源表的数据,Map输出时候以Join on条件中的列为key,如果Join有多个关联键,则以这些关联键的组合作为key;
Map输出的value为join之后所关心的(select或者where中需要用到的)列;同时在value中还会包含表的Tag信息,用于标明此value对应哪个表;
按照key进行排序;
2)Shuffle阶段:
根据key的值进行hash,并将key/value按照hash值推送至不同的reduce中,这样确保两个表中相同的key位于同一个reduce中