文章目录

  • Hive的数据倾斜
  • 数据倾斜是什么?
  • 主要表现
  • 产生数据倾斜的原因
  • 空值产生的数据倾斜
  • key分布不均匀
  • 大小表关联产生数据倾斜
  • 大表大表关联


Hive的数据倾斜

数据倾斜是什么?

顾名思义,就是数据分布不均匀,某个节点数据大量集中,而另外的节点数据量却很少。

主要表现

一个节点的任务很快就跑完了,而另外一个节点的任务很久迟迟不结束,这就是典型的数据分布不均匀。

产生数据倾斜的原因

1、key 分布不均匀

2、业务数据本身的特性

3、建表考虑不周全

4、某些HQL语句本身就存在数据倾斜

空值产生的数据倾斜

以一张表为例(数据已经进入各个节点)

hive计算数据分布 hive数据分布不均匀_hive


这张表里gender列存在一些空值,根据HashPartition,会有三种数据分配到三个节点。

这个时候解决办法是:

1、可以选择先将没有null值得两张表先join,最后再union all 有空值的表,将空值连接到最下面。
 user_id 为空的不参与关联
  
select * from log a join user b on a.user_id is not null and a.user_id = b.user_id
2、补全空值(数值符合高斯分布)
可以将空值赋予一个字符串加一个随机值,例如concat('hive',rand()),这样可以将空值打散

ps:如果说是age这列存在空值,可以采取中位数的方式,一般来说,数据符合高斯分布,说白了就是正态分布,也就是在最小值和最大值之间徘徊,所以可以取中位数。数据符合高斯分布,也就认为数据是可靠的。

或者说可以根据实际考察结果根据男女比率来填充null值,这样的数据是符合高斯分布的,也就认为是可靠的。

key分布不均匀
一种数据过多,一种数据过少且数据还没有打散进入各个节点,可以加盐打散分散到各个节点。
以下表为例,可以在gender后加上一个随机数再hash就可以打散分散到各个节点。
或者可以将age+gender合并成一列再hash,然后分散到各个节点

hive计算数据分布 hive数据分布不均匀_数据倾斜_02

大小表关联产生数据倾斜
解决方法:使用map join(只支持inner join)

因为数据交互的过程中存在shuffle,就像需要两张表join的时候,需要数据就拉取数据,必然存在数据交换,但是将小表作为内存存在每个节点上,自己的数据和自己关联不存在shuffle这一说法

在低版本中,就是hive0.11版本之前,强制两张表关联,就是将小表发到 各自节点上,目前高版本中,开启map join,默认是开启的

0.11版本之前
强制执行map join
select /*+mapjoin(表名)*/ #将小表强制放入内存
from t1 join t2 on t1.field1=t2.field;
 
高版本:默认开启
set hive.auto.convert.join=true; //设置 MapJoin 优化自动开启
set hive.mapjoin.smalltable.filesize=25,000,000 //设置小表不超过多大时开启 mapjoin 优化
大表大表关联

解决方法:将大表切分成小表,然后再分别map join