数据倾斜的产生、解决方法

数据倾斜在哪里产生的?

数据倾斜是在shuffle中产生的,shuffle过程中造成了下游task的数据任务不均衡

什么是数据倾斜?

数据倾斜就是发生在shuffle类的算子中,在进行shuffle的时候,必须将各个节点的相同的key拉到某个节点上的一个task来进行处理,比如按照key进行聚合和join操作等,这个时候其中某一个key数量量特别大,导致某个task任务运行缓慢,其他task都运行速度很快,这个是时候就就发生了数据倾斜了。

在进行shuffle的时候,需要把相同key的数据发往下游同一个task,如果某个或某几个key的数量特别大,则会导致下游的某个或某几个task所要处理的数据量特别大,也就是要处理的任务负载特别大

如何解决数据倾斜问题?

准备工作

1、定位到数据倾斜的代码
导致数据倾斜的问题就是shuffle算子,所以我们先去找到代码中的shuffle的算子,比如distinct、groupBYkey、reduceBykey、aggergateBykey、join、cogroup、repartition等,那么问题一定就出现在这里

找到shuffle类的算子之后,我们知道一个application分为job,那么一个job又划分为多个stage,stage的划分就是根据shuffle类的算子,也可以说是宽依赖来划分的,所以这个时候我们在spark UI界面上点击查看stage,那些执行时间比其他长的太多的,我们就可以大概率推断是这里发生了数据倾斜,然后我们就找到了发生数据倾斜的stage了,然后根据stage划分原理,我们就可以推算出来发生倾斜的那个stage对应的代码中的哪一部分了。

2、知道到底是哪个key数据量特别大导致的数据倾斜
使用采样算法
原理就是:所有key中,把其中每一个key随机取出来一部分,然后进行一个百分比的推算。

这是用局部取推算整体,虽然有点不准确,但是在整体概率上来说,我们只需要大概之久可以定位那个最多的key了。

正式解决

方案一:提高shuffle 的并行度
下游的task越多,分配到每个task的key就会相对更少,但这种方法只能说一定程度缓解数据倾斜问题,对于某一个数量特别大的key来说,效果也不是很好。

方案二:两阶段聚合(局部聚合+全局聚合)
用这个方法就可以解决大部分聚合运算场景的数据倾斜。

方案三:将reduce join转整map join
这种方案有假定前提:比如有两个rdd进行join操作,其中一个rdd的数据量不是很大,比如低于1个G的情况。

具体操作是就是选择两个rdd中那个比较数据量小的,然后我们把它拉到driver端,再然后通过广播变量的方式给他广播出去,这个时候再进行join 的话,因为数据都是在同一Executor中,所以shuffle 中不会有数据的传输,也就避免了数据倾斜,所以这种方式很好。

扫描二维码关注公众号,回复: 12405973 查看本文章

缺陷:如果两个rdd都很大,都超过10个G,那么这个方法就不合适了,因为数据量太大了,广播变量还是需要太大的消耗

方案四:采样倾斜key并分拆join操作
1.对包含少数几个数据量过大的key的那个Rdd,通过sample算子采样出一份样本来,然后统计以下每个key的数量,计算出来数据量最大的是哪几个key。
2.然后将这几个key对应的数据从原来的rdd中拆分出来,形成一个单独的rdd,并给每个key都打上n以内的随机数作为前缀,而不会导致倾斜的大部分key形成另外一个rdd。
3.接着将需要join的另外一个rdd,也过滤出来那几个倾斜的key对应的数据并形成一个单独的rdd,将每条数据膨胀成n条数据,这n条数据都按顺序附加一个0~n的前缀,不会导致倾斜的大部分key也形成另外一个rdd。
4.再将附加了随机前缀的独立rdd与另外一个膨胀n倍的独立rdd进行join,此时就可以将原先相同的key打算成n份,分散到多个task中去进行join了。
5.而另外两个普通的rdd就照常join即可。
6.最后将两次join的结果使用union算子合并起来即可,就是最终join结果。

总结

数据倾斜是在shuffle中产生的,shuffle过程中造成了下游task的数据任务不均衡
数据倾斜常见的场景就是那些需要shuffle的场景,比如reduce,reducebykey,join,groupbykey……

对于数据倾斜的通用做法是,增大shuffle的并行度,即增加下游task数量,此法不一定能解决

1,对于聚合运算场景,那就分两阶段聚合

2,对于join场景,如果是大小表,则使用map端join思想;如果两表都很大,则仔细回到前文品“分拆join大法”

Spark和MapReduce解决数据倾斜的思路是一样的,而hive底层不是Spark和MapReduce,hive在解决数据倾斜时也就是解决Spark或者MapReduce的数据倾斜问题。

猜你喜欢

转载自blog.csdn.net/weixin_43648241/article/details/109007380