现象
个别task执行及其缓慢

内存溢出
有的跑的慢的task,跑着跑着就oom啦
原因
一般是发生了shuffle类的算子。比如:distinct、groupByKey、reduceByKey、aggregateByKey、join、cogroup等。如果某个key数量过大,就会发生倾斜。
定位
代码


结果

定位
key ==101和103,数据数量明显倾斜。
解决方法
单表数据倾斜优化
情景
聚合类shuffle,部分key数据量较大。
解决
一般不需要手动解决,因为spark有预聚合(类似MR的combiner)。
HashAggregate —> Exchange —> HashAggregate
分片内部预聚合 —> 发送到reducer端 —> 聚合
例外情况
当大Key分布在不同分片时,
使用两阶段聚合(加盐局部聚合 + 去盐全局聚合)
Join数据倾斜优化
广播
有大小表的情况,前几篇里有记载,不赘述
加盐
拆分大key,打散大表,扩容小表
步骤
1、抽样倾斜表
拆分倾斜key(skew)和没有倾斜key(common)两个数据集。
倾斜表 不倾斜表
id id
skew 101
101 102
103 103
104
common 105
102 106
104 107
105
106
107
2、加盐倾斜表
将skew部分数据加随机前缀(可以保留之前的key,这样后面就不用去盐操作啦)。
3、扩容不倾斜表
不倾斜的表,整体与随机前缀作笛卡尔成绩(扩充N倍)。
倾斜表 skew加盐(1到3随机取前缀) 不倾斜表 扩容不倾斜表
id id id id
skew 101 1_101
101 1_101 2_101
103 2_103 3_101
102 1_102
2_102
3_102
common 103 1_103
102 2_103
104 3_103
105 104 1_104
106 2_105
107 3_106
105 1_105
2_105
3_105
106 1_106
2_106
3_106
107 1_107
2_107
3_107
4、union join的结果集
(打散skew表 join 扩容不倾斜表) union (common表 join 不倾斜表)
举例
1、拆分倾斜的key

2、将倾斜的key,随机加36种前缀,分到不同分区

3、不倾斜的表进行扩容,扩大36倍

4、倾斜大key与扩容后的表进行join

5、没有倾斜的key和不倾斜表join

6、两个join的结果进行union
注意:这里没有去盐,是因为保留了原始key。
2036

被折叠的 条评论
为什么被折叠?



