spark一次倾斜引发的思考

9 篇文章 1 订阅

场景:1大2小表关联

其中a表4亿+行,300G左右,b表几w行,17M左右,c表几十w行, 90M左右

其中b为维表,c为a的子集,a、c以a主键关联(主键关联不怎么会倾斜),a、b为维度关联

 

 

 上面为3个stage的截图,最后的stage发生了严重的倾斜,已经完成的task,最多shuffle read了500多M数据,这几个没跑完的都是几G,甚至10几G,下面为每个statge的dag

 

 

 

从dag可以看出来,先读c,a、b先join,竟然不是map join,然后a、b的shuffle read结果再与c(broadcast) join,所以倾斜必然是b表引起的,然后去a表查看a、b关联字段的降序top20 select 关联字段,count(1) from a group by 关联字段

前面是字段,后面是count(1),最多的竟然占了6000多w

升序top10,都是1,罪魁祸首找到了,就是a、b关联引起的

思考:该怎么解决?

1.所有小表直接map join

最理想的情况是什么,针对1大2小,直接2小都广播,要是impala的话, join b、c前加[broadcast]完事

为什么spark没这么处理呢,map join有个参数,将多个小表直接一个mapjoin,去7180找参数,瞅瞅默认多少

20M, 忒小了,手动set大点

直接设置成3G,不信广播不出去,忽略下面的stageid为2、3的,截多了

这是设置完成后的,直接b,c成一个stage对应stage0,然后与a map join,对应stage1,13分钟搞定,打完收工

2.调整join顺序

思考:为啥a要先与b关联,后面shuffle read倾斜很严重,然后再广播c关联呢, 改sql,mapjoin的参数不改了,sql改成如下

select
xxxxx
from a 
left join c on xxx 
left join b on xxx

 也比较快,stage0读b表,然后a、c关联

呜呜呜,优化器越不智能的数据库,调优技巧越多,哈哈哈,说的就是你impala,请长点心

 

3.扩展

要是关联维表多,合成map join出去肯定比较耗内存,甚至超了被yarn kill掉,调整join顺序,每个维度倾斜都比较严重得话,咋调整后面的也倾斜,所以只能扩容维表,这也是不得已的方法,比起set俩参数,改改join顺序,这个可能还得创几个中间表

select 
xxx
from 大表
left join 小1 on xxx
left join 小2 on xxx
.....

假设现在没法都map join,只能扩容维表

比如大表 join 小表 on field=field,关联字段在数仓里基本都是小表的主键,但在大表里可能分布极不均匀,所以创多个专门为了处理倾斜而存在表,100行或1000行,就一个字段,然后从0-100,或者从0-1000,先维表和倾斜表关联,将临时表的关联键每条处理成0field...100field,然后再与大表关联,on concat(rand()*100,大表.关联键)=临时表.field

 

4.join顺序?

截图就不沾了, 之前瞅hive官网,建议多表关联大表放最后边,impala\kudu建议大表放最前边

是什么原因引发这么大的差异呢?hive的解释是:关联到最后,关联的中间结果会在内存做hash表,然后网络一条条拉取大表和hash表关联,大表放最后可以减少构建的hash表的内存占用

impala咋解释的:大表要放最前边,因为第一个表是从本地磁盘直接读出来的,而后面关联的表或者中间物化表都得网络fetch,所以大表最前边

impala只读本地数据,不像spark,hadoop基于yarn的,分级,process_local直到any

所以impala如果最大表与后面的关联能过滤掉很多数据,那么后的网络fetch可以少拉取很多数据,map join同理,如果map join能干掉大表一半数据,那后面的关联shuffle read性能就提高了

left deep tree?一句话解释就是:多表关联,也是先2个关联,然后结果物化再与后面的表关联,所以我们能做的事情就是保证每次的物化结果都是最小的 ,感兴趣的去搜下吧,讲的就是优化器join顺序,可惜的是spark、impala都比较不智能,

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值