文章目录
今天我们来详细介绍下Spark数据倾斜
1. 单表数据倾斜
1.1 倾斜场景
某张表个别key的数据量特别大
1.2 解决方案
加盐局部聚合+去盐全局聚合,也就是所谓的两阶段聚合;这个加盐局部聚合就是在map端提前做的一个预聚合,也就是相当于MR将缓冲区的数据溢写到磁盘上的时候做的一个聚合。去盐全局聚合时shuffle之后在reduce端做的一个聚合。
2. 大表Join小表倾斜
2.1 倾斜场景
大表Join小表造成数据倾斜,且小表不是太大,默认小表是小于等于25M
2.2 解决方案
可以开启MapJoin,将小表广到Executor的内存中,直接避免shuffle的产生。
3. 大表Join大表倾斜
3.1 倾斜场景
大表Join大表造成数据倾斜,其中一张表某个key的数据量特别大,另一种那个表分布比较均匀,但是另一张表也是挺大的,我们不能粗暴的将其广播到Executor内存中。
3.2 解决方案
像这种情况造成的倾斜,首先我们要确定大表里倾斜的key有哪些,(大表为A,中表为B)然后将这些数据过滤出来,形成一张倾斜表A1,并且给倾斜的key加上随机数n,然后剩余的不倾斜的数据我们形成一张表A2;对于另一张表B,我们我们将其扩容n倍,称为B1,然后将倾斜表A1和扩容表B1进行Join,没有倾斜的A2和B进行Join,最后将两者结果进行Union起来。
4. 两表Join时空值过多倾斜
4.1 倾斜场景
两张表Join时,空值太多,造成的数据倾斜
4.2 解决方案
这里我们有两种解决方案,第一种就是给空值附上随机数,在join条件那里使用case when判断一下,加上随机数就行,第二种就是在两张表join之前,将空值数据过滤出来,join之后再union all上为空的数据。