spark调优之数据倾斜

一、数据倾斜概述

  • 数据倾斜原理
    • 在进行任务计算shuffle操作的时候,少数的task被分配到了大量的数据,是其他task的十倍甚至百倍,导致最终整个spark任务计算特别慢。
  • 如何定位原因
    • 主要是根据log日志信息去定位
    • 分析定位逻辑,由于代码中有大量的shuffle操作,一个job会划分为多个stage,我们可以观察任务的UI界面,观察是哪一个stage中的task分配主句不均匀,根据代码逻辑分析是哪个算子导致的
    • 某个task莫名内存溢出的情况,我们可以直接看yarn-client模式下本地log的异常栈,或者是通过YARN查看yarn-cluster模式下的log中的异常栈,但task内存溢出并不一定是数据倾斜引起的。
    • 查看导致数据倾斜的key的分布情况,如果是Spark SQL导致的数据倾斜,那就看看所查询表中key的分布情况,如果是RDD执行shuffle算子导致的数据倾斜,则可以先simple抽取数据,countbykey查看各个key的数据量分布,collect/take到客户端打印查看。
  • 数据倾斜的后果
    • spark中的stage的执行时间受限于最后完成的task,拖慢了整个程序的运行速度
    • 过多数据在同一个task中运行,会把executor内存撑爆,导致OOM

二、使用Hive ETL预处理数据

  • 适用场景:Hive表中数据本身key分布不均匀
  • 实现思路:对Hive进行ETL预处理,将spark中的shuffle操作提到ETL中,这样spark中就不会有shuffle操作了
  • 优点:实现起来比较简单,spark性能大幅提升
  • 缺点:治标不治本,Hive ETL中还是会发生数据倾斜

三、过滤少数导致倾斜的key

  • 适用场景:只有少数key导致数据倾斜
  • 实现思路:如果判断导致倾斜的key对于作业的执行和计算结果不是特别重要,就直接过滤掉。在Spark SQL中可以使用where子句过滤掉,在RDD中使用filter算子过滤掉
  • 优点:实现简单,效果很好
  • 缺点:适用场景不多

四、提高shuffle操作的并行度

  • 适用场景:数据倾斜无法避免,需要被处理
  • 实现思路:设置参数:spark.sql.shuffle.partitions,或者是给shuffle算子传入一个参数,比如reduceByKey(1000),可以让原本分配给一个task的多个key分配给多个task
  • 优点:可以有效缓解数据倾斜的影响
  • 缺点:没有根除数据倾斜,效果有限

五、两阶段聚合(局部聚合+全局聚合)

  • 适用场景:对RDD执行聚合类算子,使用Spark SQL中的group by语句进行聚合
  • 实现思路:先给每个key都加上一个随机数前缀,进行局部聚合,再将前缀去掉进行全局聚合。这样将原本相同的key分散到多个task上做局部聚合,再进行全局聚合
  • 优点:对于聚合类的shuffle操作导致的数据倾斜效果不错,通常可以解决掉数据倾斜
  • 缺点:仅仅适用于聚合类的shuffle操作

六、将reduce join转为map join

  • 适用场景:对RDD进行join操作,或者Spark SQL中使用join语句,而且join操作中的一个RDD或者表的数据量比较小
  • 实现思路:不使用join算子,而使用Broadcast变量与map类算子实现join操作,完全规避掉shuffle操作。将较小RDD中的数据通过collect算子拉取到Driver端的内存,对其创建一个Broadcast变量,对另一个RDD进行map,判断如果key相同则将两者的数据按需要的方式拼接起来。
  • 优点:规避了shuffle操作
  • 缺点:适用场景少,适用于一个大表和一个小表的情况

七、采样倾斜key并分拆join操作

  • 适用场景:两个RDD/Hive表进行join的时候数据量都比较大,适用于两个表中其中一个表key倾斜,而另一个表key数据分布均匀的情况
  • 实现思路:1.先使用采样,采出一份样本,统计一下每个key的数量,取出最大的几个key 2.将这几个key对应的数据从原来的RDD中拆分出来,形成一个单独的RDD,并给每个key都打上0-n随机数作为前缀,不会导致倾斜的key数据形成另外一份RDD 3.将需要join的另一个RDD也过滤好生成两份RDD,并将有倾斜key的RDD每条数据都加上0-n的前缀,膨胀成n条 4. 加了随机前缀的RDD与膨胀的RDD进行join,这样就将相同的key打散成n份,分散到多个task中去了 5.将另外两个RDD也进行join,并将两次结果union合并起来
  • 优点:对于少数key导致的数据倾斜使用该方式最有效的打散key
  • 缺点:如果导致倾斜的key比较多的话,这种方式不太合适

八、使用随机前缀和扩容RDD进行join

  • 适用场景:大量key导致的数据倾斜,这时chaifenkey就没有意义了
  • 实现思路:对于其中一个RDD每条都加上n以内的随机数,另一个RDD则膨胀n倍,两个RDD进行join
  • 优点:对于join类的数据倾斜基本都可以解决
  • 缺点:比较吃内存
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值