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的内存。
场景3的解决方案的缺点:
优点:对join类型的数据倾斜基本都可以处理,而且效果也相对比较显著,性能提升效果非常不错。

缺点:该方案更多的是缓解数据倾斜,而不是彻底避免数据倾斜。而且需要对整个RDD进行扩容,对内存资源要求很高。
当在Hive中进行JOIN操作时,数据倾斜是一个常见的问题。数据倾斜是指在JOIN操作中某些数据分布不均匀,导致部分任务执行时间过长,而其他任务执行时间很短的情况。 以下是一些可以尝试的方法来处理数据倾斜问题: 1. 增加并行度:通过增加并行度来将任务分散到更多的节点上。可以使用以下方式来增加并行度: - 设置MapReduce任务的数量(mapreduce.job.reduces)。 - 使用Hive的特殊配置参数,如hive.exec.reducers.bytes.per.reducer和hive.exec.reducers.max。 - 使用Distribute By或Cluster By子句来更好地分发数据。 2. 优化结构:考虑对进行合理的分区和存储格式设计,以便更好地利用并行处理能力。合理的分区和存储格式可以减少数据倾斜的发生。 3. 使用Bucketing:Bucketing是一种将数据划分为固定数量的桶,并将数据均匀地分布在这些桶中的方法。通过使用Bucketing,可以减少JOIN操作中数据倾斜的影响。 4. 考虑使用Map-side Join:如果一个很小而另一个,可以考虑使用Map-side Join。Map-side Join会将小完全加载到内存中,并在Map阶段进行JOIN操作,避免了数据倾斜的问题。 5. 使用随机数进行均匀分布:如果数据倾斜发生在某些特定的列上,可以尝试使用随机数来将数据均匀分布到不同的Reducer中。 6. 使用拆分JOIN操作:将一个JOIN操作拆分为多个较小的JOIN操作,可以减少数据倾斜的影响。 以上是一些常用的处理Hive数据倾斜问题的方法,具体的选择取决于数据的特点和实际情况。在实践中,可能需要尝试多种方法来找到最适合的解决方案
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

雾岛与鲸

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值