当前位置:   article > 正文

hive join 数据倾斜解决方案

hive join 数据倾斜解决方案

理解join的运行原理

select u.name, o.orderid from order o join user u on o.uid = u.uid;
join运行原理

理解join的作用?

通常我们在执行join的时候,通常是一个表a包含很多的key, 这个key是可重复的,一张表b中对应的key是不能重复且唯一的。(如果两张表包含多个相同的key进行join操作,会产生笛卡尔积, 产生多个结果,显然在生产环境中,这是我们不想看到的)

为什么会产生数据倾斜?

造成Join数据倾斜的原因是Join on的key分布不均匀。 mapreduce底层是根据 key的hash值%reduce个数 来进行数据分区的,所以相同的key对打到同一个reduce进行处理。
key值分布不均匀,倾斜key数据都被打到同一个reduce上进行处理, 造成数据倾斜问题。

场景1: 一张大表一张小表的情况?

采用MapJoin的方式, 将小表加载到内存中,执行map端的join, 中间不产生shuffle, 就不会有数据倾斜的情况出现了。

场景2: 两张大表,部分key导致倾斜的情况?

倾斜的key落到一个reduce task上, 导致某一个reduce Task执行缓慢。
对导致倾斜的key单独处理(这里的详细的处理方式就是场景3的处理方式),和没有导致倾斜的key执行的结果进行 union all。
例如key空值过多导致的数据倾斜问题。

优点:对于join导致的数据倾斜,如果只是某几个key导致了倾斜,采用该方式可以用最有效的方式打散key进行join。而且只需要针对少数倾斜key对应的数据进行扩容n倍,不需要对全量数据进行扩容。避免了占用过多内存。

缺点:如果导致倾斜的key特别多的话,比如成千上万个key都导致数据倾斜,那么这种方式也不适合。

场景3: 两张大表,很多个key导致倾斜的情况?
有很多倾斜key的表a, key分布均匀的表b

1、给表a的key加上100以内的随机前缀,将数据打散 (ceiling函数,向上取整)
select concat_ws("_", ceiling(rand()*99), key) from a;                   tmp_a

2、将表b扩容100倍,给key加上100以内的随机前缀

产出一张临时表, tmp_id, 表中的内容如下: 
id
1
2
3
4
...
99
100

将表b和表tmp_id进行join, 产生笛卡尔积
select concat_ws("_", c.id, b.key) as key, value from b join tmp_id c;     tmp_b

这样表b的数据就扩容了100倍

然后将 tmp_a 和 tmp_b 进行join: 

select a.key, a.value, b.value 
from tmp_a a join tmp_b b 
on a.key = b.key;

这样的话,key就均匀地分配到不同的reduce上了,而且都能和对应的数据关联上,注意执行完成之后,对相应的key进行去掉前缀的操作。

由于对表b进行了扩容,这里需要对reduce端的内存做相应的调整,增加reduce task的内存。
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
场景3的解决方案的缺点:
优点:对join类型的数据倾斜基本都可以处理,而且效果也相对比较显著,性能提升效果非常不错。

缺点:该方案更多的是缓解数据倾斜,而不是彻底避免数据倾斜。而且需要对整个RDD进行扩容,对内存资源要求很高。
  • 1
  • 2
  • 3
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/木道寻08/article/detail/805674
推荐阅读
相关标签
  

闽ICP备14008679号