Spark项目之用户行为【性能优化9】数据倾斜优化

Spark数据清洗优化方案

1、提前聚合

1.1、源数据聚合

实际场景:在Hive表跑批的时候,提前聚合部分数据,避免在Spark阶段的shuffle

1.2、聚合较粗的粒度,逐渐放细

实际场景:本来要统计city的人数,可以先统计<city,sex>粗粒度一点的数据

2、过滤某些Key(要考虑需求和业务场景)

实际场景:业务和需求允许的情况下,可以过滤部分倾斜的key

3、增加reduceTask的并行度(生产紧急使用,治标不治本)

使用方法

JavaPairRDD<Long, Long> clickCategoryId2CountRDD = clickCategoryIdRDD.reduceByKey(

                new Function2<Long, Long, Long>() {

                    private static final long serialVersionUID = 1L;

                    @Override
                    public Long call(Long v1, Long v2) throws Exception {
                        return v1 + v2;
                    }

                },1000);

4、针对reduceByKey/groupByKey的数据倾斜,在Key前面增加一个随机数,相当于把数量分布较多的Key打散,先局部聚合,再映射会本身的Key,最后再进行全局聚合的过程,图解如下

在这里插入图片描述
有点类似Hive数据倾斜的情况

适用:已经找出倾斜的Key,直接对倾斜Key进行打散操作,以及聚合的逻辑可以进行拆分局部和总体的,比如加减乘等
不适用:聚合逻辑复杂且不支持局部聚合,比如求平均值等

实际项目操作:
clickCategoryIdRDD.reduceByKey

1、在品类ID聚合之前,可以先映射随机数前缀,scala:map(),java:maptopair()
2、初步的reduceByKey
3、初步聚合后,再映射回本来的Key, scala:map(),java:maptopair()
4、全局的reduceByKey

5、针对(大表小表)join类型的数据倾斜,使用mapjoin优化

场景:适合大表和小表之间join,数据量差异比较大,且有Key分布不均的情况
原理:将小表做成广播变量broadcast,由collect分发到所有的Excetor_Block中,每部分数据进行map操作的时候,就可以直接获取对应Key在broadcast中的value,并进行mapToPair 实现 join,就不会有shuffle阶段,形成数据倾斜
注:被广播的表的大小不超过,spark.sql.autoBroadcastJoinThreshold 所配置的值,默认是10M

不适用:两个大表关联,且有数据倾斜的Key的情况

总结:就算没有数据倾斜,单单从优化的角度,也是可以考虑这种手段的
实际项目经验:
大表join小表,已经做了 broadcast,为什么走的还是shuffle,join
1,是不是直接用RDD来进行broadcast,会直接报错,以为RDD不存储数据,只能把RDD的结果broadcast
2,broadcast的数据是不是超过设定的参数值,导致广播失败,omm
3,用DataFrame广播的时候,广播的是dataFrame这个变量,而不是里面的素有数据

    val smallTableBroadCastValue = sc.broadcast(smallTable).value

//转换成
val result = bigTable.join(org.apache.spark.sql.functions.broadcast(smallTable), "joinkey")

6、join类型两个大表之间的数据倾斜

场景:倾斜Key比较少,或仅有一个的情况下可以使用
原理:把原RDD拆分成两个部分,一个是倾斜Key的RDD,一个是非倾斜Key的RDD,分别与目标表join之后,再union再一起,达到最终的效果
实现原理:拆分前
在这里插入图片描述

本来相同Key会分到同一个task中,导致数据倾斜

拆分后
在这里插入图片描述

拆分后,只有一个key,就可以把一个key的数据分到多个task中,均衡处理

不适用:倾斜Key较多的情况下不适用

7、join类型倾斜,两个大表之间join,且倾斜Key较多的情况下

场景:两个大表之间join,且倾斜Key不是一个或者几个,很多个
原理:一般是将小表的数据进行扩容打散(flatMap),加上随机数prefix,一般是10,如果能找到倾斜Key,可以扩容更大的倍数,大表的key,添加一个同等倍数的随机数,0-10,然后再进行join,join再映射,再join,就不会有数据倾斜问题

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值