导读:上两期,我们分别讲了通过提高并行度和自定义分区策略来解决数据倾斜的方法,同时我们也讲到了他们的共同缺点:针对于不同key倾斜到同一个节点到场景。那如果是同样的key太大怎么办呢?如何将同一个key分配到不同的节点呢?答案就是通过对key增加前后缀的方式,这样就可以重新为这些数据划分分区了。这种方式解决起来比较麻烦,我们可以一步一步来。系列完成会把代码开源~
本文经授权转自公众号DLab数据实验室
作者 | 小舰
出品 | DLab数据实验室(ID:rucdlab)
增加随机前缀
1.数据准备
由于上面两期,我们都是用的1.2亿条数据的单表来进行测试的,本节的场景需要涉及到两表join,因此我们再次构造一个小表。
本期我们就用这两个表进行join,再简单回顾一下那1.2亿条数据的表cyj_skew,其中有1亿条数据是不重复的,后面的2000万条数据集中在了50个key中,所以这50个key每个key会重复40万次;那我们可以简单估计,cyj_skew中的50个重复key与cyj_skew_small 500个重复key相join,二者共有的一个重复key会产生100*40w=4000w条结果,这个数据量比起其它key来讲会大千万倍。所以我们预想肯定会产生数据倾斜。
2.判断数据倾斜
如何判断数据倾斜呢?如果我们看到在任务执行的时候,大部分task都执行完毕,只剩若干个任务还在运行,并且运行时间和处理数据量远超其他task,则可以认为发生了数据倾斜,如下图所示,时间和数据量相差比较大。
3.判断倾斜键
因为数据倾斜键是我们自己模拟出来的,所以我们知道cyj_skew和cyj_skew_small分别有50和500个重复键,那我们需要找出他们共有的重复键,对这些重复键进行优化。
4.添加随机前缀
首先,我们需要查询出这两个表对数据,得到两份数据DataFrame
然后,对这些数据的共有key进行加前缀操作
最后,我们重新将添加前缀的数据进行join计算
5.未优化性能结果
我们可以看到无论是时间还是数据量上都差别很大,而且总运行时长为11分钟左右
6.优化性能
我们可以看到,整体的时间和数据量相差不大,数据倾斜现象基本消失,整个任务运行3分钟左右。
总结
好了,到这里我们就把数据倾斜常用的处理方式介绍完了。回顾一下我们主要介绍了三种方法--增加并发度、自定义分区和添加随机前缀。每个方法各有优劣,一般来讲都是从简到难来选择解决方案,如果通过提高并发度能解决,就不用后面到方法了。当然,在实际的场景中,可能要结合这几种方法来综合调优,欢迎大家一起讨论交流~
DLab数据实验室 发起了一个读者讨论交流区
●Spark训练营(一)-- 开发环境搭建及wordCount实战
●Spark训练营(二)-- SparkStreaming流计算组件wordCount实战
●Spark训练营(三)-- GraphX图计算组件最短路算法实战