1.HiveETL预处理
简述:预先对数据按照key进行聚合,或者是预先和其他表进行join,然后在spark作业中针对的数据源就是预处理后的Hive表,不需要使用原先的shuffle类算子执行。
使用场景:导致数据倾斜的是Hive表。如果Hive表中的数据本身很不均匀(比如某个key对应100w数据,而其他key只对应10w),而且业务场景需要频繁使用Spark对Hive表进行分析操作。
2.过滤少数导致倾斜的key
简述:如果少数几个数据量特别多的key对作业的执行和计算结果不是特别重要的话,直接过滤掉那几个少数key。
使用场景:如果发现导致倾斜的key就少数几个,而且对计算本身的影响不大的话。
3.提高shuffle操作并行度
简述:提高shuffle类算子并行度,治标不治本。
使用场景:必须要对数据倾斜时,优先使用这种方案,最简单。
4.两阶段聚合
简述:第一次打散前缀再聚合,第二次去掉随即前缀再全局聚合。
使用场景:对RDD执行reduceByKey等聚合类shuffle算子或者在SparkSQL中使用group by语句进行分组聚合时。
5.将reduce join转换成map join
简述:小表广播到大表所在executor进行map join。
使用场景:对RDD使用join类操作时,或者是在Spark SQL中使用join语句时,而且join操作中的一个RDD数据量比较小。
6.采样倾斜key并分拆join操作
简述:对少数几个key数据量大的RDD采样并给行最多的打上n内的随即前缀,join的另一个RDD过滤出这些key并每个都膨胀为n条打赏0-n前缀的,进行join。正常分布的也进行join,最后两边union即可。
使用场景:两个RDD/Hive表进行join的时候,如果数据量都比较大,且数据倾斜是因为其中某一个RDD/Hive表中的少数几个key的数据量过大,而另一个RDD/Hive表中的所有key都分布比较均匀。
7.使用随即前缀和扩容RDD进行join
简述:将大量数据倾斜key的RDD,每条数据都打上100以内的随即前缀,将另一个key分布较均匀的RDD膨胀100被。两个处理过后的RDD进行join。
使用场景:如果在进行join操作时,RDD中大量的key导致数据倾斜。