hive学习之hive数据倾斜以及优化

 

一、数据倾斜的原因

  1)、key分布不均

  2)、业务数据本身的特性

  3)、建表时候考虑不周

  4)、某些sql语句本身就有数据倾斜

关键词 情形 后果

join

 

①其中一个表较小,但是key集中

②大表与大表,但是分桶的判断字段0值或者

空值过多

①分发到某一个或者某几个reducer上的数据远高于平均值

②这些空值都由一个reduce处理,处理效率会非常慢

group by  group by 维度过小,某个值的数量过多 处理这个值的reduce会非常耗时
Count Distinct 某特殊值过多 处理次特殊值的reduce耗时

 

 

 

 

 

 

二、数据倾斜的表现

  任务长时间维持在99%货100%,查看任务监控页面,发现只有少量的(1个或者几个)reduce子任务未完成,以为这些reduce处理的数据量与其他reduce处理的数据量差异过大。

  单一reduce的记录数与平均记录数差异过大,通常可能达到3倍可能更多,最长时长远大于平均时长。

三、数据倾斜的解决方案

3.1 参数调节

  对于group by产生倾斜的问题。

  1)、set  hive.map.aggr = true;

  开启map端的combiner

  2)、set  hive.groupby.skewindata = true;

  有数据倾斜的时候开启负载均衡,当选项设置为true的时候,生成的查询计划会有两个MR job 。第一个MR job中,map的输出结果会随机分布到reduce,每个reduce做部分聚合操作,并输出结果,这样做的结果是相同的Group by Key有可能分发到不同的reduce上,从而达到负载均衡的效果,第二个MR Job再根据第一个Map job预处理的数据结果安装Group by key分布到reduce中(这个过程可以保证相同的group by key被分布到同一个reduce中),最后完成最终的聚合操作。具体流程如下图。

  3)、调节reducer数量

  set mapred.reduce.tasks = 20;

  4)、在同一个SQL中不同的job是否可以同时运行。(默认为false)

  set  hive.exec.parallel = true;

  5)、增加同一个sql允许并运行的最大线程数

  set  hive.exec.parallel.thread.number=8;

  6)、设置reducer内存大小

  set  mapreduce.reduce.memory.mb = 4096;

  set  mapreduce.reduce.java.opts =-Xmx3584m;

 

3.2 SQL语句调节

  1)、大小表join

  使用 mapjoin ,让小的维度表先进内存。在map端完成join,不经过reduce。

  2)、大表join大表

  非法数据太多,比如null

  ①、如果null值不要,可以使用where条件直接过滤掉。

select * from 
(select  * from  t1 where country is not null) tt1
join 
(select  * from  t2 where country is not null) tt2;

  ②、把空值的key变成一个字符串加上随机数,把倾斜的数据分不到不同的reduce上,由于null值关联不上,处理后不影响最终结果

select  * from 
(select case when user id is null then concat(rand(),"test")) else user_id from t1)tt1 inner join t2 tt2 on tt1.user_id=tt2.user_id;  

  ③、count distinct大量相同特殊值

  count distinct时候,将值为空的情况单独处理,如果是计算count distinct ,可以不用处理,直接略过,在最后结果中加1。如果还有其他计算,需要进行group by ,可以先将值为空的记录单独处理,在和其他计算结果进行union。

  采用sum() group by的方式来替换count(distinct)完成计算。

select  count(distinct c1)+1 from tt where c1 is not null;

select sum(1)+1 from  tt where c1 is not null group by c1;

select  count(distinct c1)+1 from tt where c1 is not null
union 
select  count(distinct c1)+1 from tt where c1 is null;

 

 

 

以上是个人整理的一些优化方式,肯定还有很多遗漏以及不足之处,欢迎各位大佬批评指正。

下面的链接是网上大佬总结的hive优化总结,个人感觉比较全面。大家感兴趣也可以看一下。

https://cloud.tencent.com/developer/article/1453464 

 

 

 

  

 

posted @ 2020-04-27 14:03  myc513  阅读(902)  评论(0)    收藏  举报