SparkSQL优化笔记-空值关联引起的数据倾斜

1、背景

        今天在做表关联也就是join时,发现了SparkSQL任务产生了数据倾斜,后续定位问题原因(两张表关联字段中包含大量空值,造成数据倾斜),并且优化脚本,大大降低了数据倾斜产生的Task时长过长问题,那么整个过程是怎么处理的呢,各位看客老爷别急,您~往下看 ↓

2、实例

       优化前执行情况:

         

       优化后执行情况:

                         

      从上图可以看到,优化后的执行速度在22分钟左右,比优化前缩短了将近一半的时间,那么是如何优化的呢,优化的点是什么呢?您~接着往下看 ↓

3、通过Web-Ui分析SparkSQL任务 

        首先先打开未优化前的任务,发现执行较长的stage一共有三个,下图已标识,分别打开1、2、3(点击Description)后看了下,发现13任务都很正常,只有2(也就是stage18)发生了数据倾斜而且倾斜很严重,为什么这么说呢,各位看客老爷您上眼 ↓

           

         

         通过上图可以发现运行最长的Task花费了18分钟,然而75个Task的平均速度只用了5.4分钟,从此处就可以看出来了,这个任务发生了很明显的数据倾斜,那么这个问题出现在哪里呢,此时我观察了运行的Sql文件,发现很多表进行关联,但是关联的表很多都是小表,而且小表基本都被我广播出去了(广播变量大小设为了100M,小于100M的都被作为变量广播到各个excutor中了),所以我把问题原因先定位到仅有的两张大表关联逻辑上。然后通过关联字段我做了下分析,我想大概定位到原因了。

4、定位原因

      

     

        看到上图估计各位也应该定位到问题原因了,(对,这位同学说的没错)就是因为关联字段空值太多造成的数据倾斜,那么问题又来了,已经定位到问题了,那么如何优化呢🙋?(好,这位同学问的问题非常好),咱们回归到出现数据倾斜的那段逻辑,本质就是因为关联字段为空数据太多所以造成的倾斜,那么我把为空的数据单独处理,非空数据单独处理不就结了(我可真是个机灵鬼,手动给自己点赞)。好了,废话不多说,直接上代码🐶。    

--优化前
insert overwrite table dbName.tableName
SELECT t01.*
FROM
  (SELECT *
   FROM dbName.tableName
   WHERE dt='20211113'
     AND businessdaydate >='20200101') t01
LEFT JOIN
  (SELECT erp_code,
          min(user_id) AS user_id
   FROM dbName.tableName
   WHERE dt='20211113'
     AND erp_code <> ''
     AND erp_code IS NOT NULL
   GROUP BY erp_code) t06 ON t01.custcardnumber = t06.erp_code 
;


--优化后

====step:1
insert overwrite table dbName.tableName
SELECT t01.*
FROM
  (SELECT *
   FROM dbName.tableName
   WHERE dt='20211113'
     AND businessdaydate >='20200101'
     AND coalesce(custcardnumber,'null') NOT IN ('null','')) t01
LEFT JOIN
  (SELECT erp_code,
          min(user_id) AS user_id
   FROM dbName.tableName
   WHERE dt='20211113'
     AND erp_code <> ''
     AND erp_code IS NOT NULL
   GROUP BY erp_code) t06 ON t01.custcardnumber = t06.erp_code 
;

====step:2
insert into table dbName.tableName
SELECT t01.*
FROM
  (SELECT *
   FROM dbName.tableName
   WHERE dt='20211113'
     AND businessdaydate >='20200101'
     AND coalesce(custcardnumber,'null') IN ('null','')) t01
LEFT JOIN
  (SELECT erp_code,
          min(user_id) AS user_id
   FROM dbName.tableName
   WHERE dt='20211113'
     AND erp_code <> ''
     AND erp_code IS NOT NULL
   GROUP BY erp_code) t06 ON t01.custcardnumber = t06.erp_code
;

        上述代码的处理逻辑非常简单,就是把为空的值单独单独处理。虽然看起来挺low的,但是效果真的是立竿见影(什么,你不信,要我拿证据出来?好的,证据我还就放这里了)。

         

         

 5、总结

        SparkSQL的优化过程是需要持续长时间迭代的,可能今天你优化完成了并且效果非常明显,可是过一段时间你会发现任务跑的又很慢了,又产生了数据倾斜。这个时候你不要着急,你要一步步分析,并且定位原因,到最后对症下药进行参数或者逻辑的调整,调优过程可能很枯燥,但是找到问题,并且优化后的结果你也会异常开心的。好了,各位看官老爷,都看到这里了,真不打算点个赞再走么,哈哈~

        

        流水不争先,争得是滔滔不绝!        

  • 3
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值