Spark数据倾斜解决办法

Spark数据倾斜解决办法

一个Spark程序会根据其内部的Action操作划分成多个job,每个作业内部又会根据shuffle操作划分成多个Stage,每个Stage由多个Task任务并行进行计算,每个Task任务只计算一个分区的数据。
Spark数据倾斜就是大量相同的key进入到了同一个分区。


数据倾斜

  • Spark数据倾斜解决办法
  • 前言
  • 一、解决办法
    • 1.数据预处理
    • 2.过滤导致数据倾斜的key
    • 3.提高shuffle操作的并行度
    • 4.使用随机key进行双重聚合


前言

数据倾斜解决的思路就是保证每个Task任务所计算的数据尽量保持均匀。数据在到达Spark之前能够做到划分得足够均匀当然是最好的,如果做不到,就要对数据进行加工,尽量保证数据的均匀,然后在进行计算,这样避免了数据倾斜现象。


一、解决办法

1.数据预处理

假设Spark的数据源来自于Hive,那么可以在Hive中对数据进行一次预处理,尽量保证数据的均匀。或者在Hive中提前对数据进行一次聚合,当数据传入Spark中后,不需要再次进行reduceByKeyO等聚合操作,没有了Shuffle阶段,从而避免了数据倾斜。

2.过滤导致数据倾斜的key

如果产生数据倾斜的key没有实际意义(比如存在很多key是“-”),对业务不会产生影响,那么可以在使用Spark读取数据时直接用filter()算子将其过滤掉,过滤掉的key不会参与后面的计算,从而消除了数据倾斜。

3.提高shuffle操作的并行度

Spark RDD的Shuffle过程与MapReduce 类似,涉及数据重组和重新分区。如果分区数量(并行度)设置得不合适,很可能造成大量不同的key被分配到同一个分区中,导致某个Task任务处理的数据量远远大于其他Task任务,造成数据倾斜。可以在使用聚合算子(例如 groupByKey()、countByKey()、reduceByKey()等)时传入一个参数来指定分区数量(并行度),这样能够让原本分配给一个Task任务的多个key分配给多个Task任务,让每个Task任务处理比原来更少的数据,从而有效缓解和减轻数据倾斜的影响。例如,在对某个RDD执行reduceByKeyO算子时,可以传入一个参数,即 reduceByKey(20),该参数可以指定Shuffle操作的并行度,也就是数据重组后的分区数量

4.使用随机key进行双重聚合

在相同的key上追加随机数字作为前缀,将相同的key变为多个不同的key,这样可以让区本被分配到同一分区中的key 分散到多个分区中,从而使用多个Task任务进行处理,解个Task处理数据量过多的问题。到这里只是一个局部聚合,接着去除每个key的随机前行全局聚合,就可以得到最终的结果,从而避免数据倾斜。这种使用双重聚合避免数据倾图的方式在Spark 中适合groupByKey()和 reduceByKey()等聚合类算子。

你可能感兴趣的:(Spark,spark)