Spark数据倾斜调优总结

Spark数据倾斜调优

  1. 你在工作当中遇到哪些数据倾斜的场景,你是如何处理的?
  2. 你在工作当中调过优吗?怎么处理的?效果怎么样?
  3. Spark Shuffle的发展过程

1. 数据倾斜原理和现象分析

  • (1)绝大多数task执行得都非常快,但个别task执行极慢

  • (2)绝大数task执行很快,有的task直接报OOM (Jvm Out Of Memory) 异常

数据倾斜如何定位原因 数据倾斜只会发生在shuffle过程中

主要是根据log日志信息去定位

  • 可能会触发shuffle操作的算子:distinct、groupByKey、reduceByKey、aggregateByKey、join、cogroup、repartition等。
  • 出现数据倾斜时,可能就是你的代码中使用了这些算子中的某一个所导致的。因为某个或者某些key对应的数据,远远的高于其他的key。

分析定位逻辑

  • 由于代码中有大量的shuffle操作,一个job会划分成很多个stage,首先要看的,就是数据倾斜发生在第几个stage中。
  • 可以在任务运行的过程中,观察任务的UI界面,可以观察到每一个stage中运行的task的数据量,从而进一步确定是不是task分配的数据不均匀导致了数据倾斜。

某个task莫名其妙内存溢出的情况

这种情况下去定位出问题的代码就比较容易了。
我们建议直接看yarn-client模式下本地log的异常栈,或者是通过YARN查看yarn-cluster模式下的log中的异常栈。
一般来说,通过异常栈信息就可以定位到你的代码中哪一行发生了内存溢出。
然后在那行代码附近找找,一般也会有shuffle类算子,此时很可能就是这个算子导致了数据倾斜。
但是大家要注意的是,不能单纯靠偶然的内存溢出就判定发生了数据倾斜。
因为自己编写的代码的bug,以及偶然出现的数据异常,也可能会导致内存溢出。
因此还是要按照上面所讲的方法,通过Spark Web UI查看报错的那个stage的各个task的运行时间以及分配的数据量,才能确定是否是由于数据倾斜才导致了这次内存溢出。

查看导致数据倾斜的key的数据分布情况

知道了数据倾斜发生在哪里之后,通常需要分析一下那个执行了shuffle操作并且导致了数据倾斜的RDD/Hive表,查看一下其中key的分布情况。

数据倾斜原因总结

  • 1、数据本身问题

    • (1)key本身分布不均衡(包括大量的key为空)
    • (2)key的设置不合理
  • 2、spark使用不当的问题

数据倾斜的后果

(1)spark中的stage的执行时间受限于最后那个执行完成的task,

因此运行缓慢的任务会拖垮整个程序的运行速度(分布式程序运行的速度是由最慢的那个task决定的)。

(2)过多的数据在同一个task中运行,将会把executor内存撑爆,导致OOM内存溢出。

2. spark中数据倾斜的解决方案

2.1、方案一:使用Hive ETL预处理数据

方案适用场景:导致数据倾斜的是Hive表。

  • 如果该Hive表中的数据本身很不均匀(比如某个key对应了100万数据,其他key才对应了10条数据),而且业务场景需要频繁使用Spark对Hive表执行某个分析操作,那么比较适合使用这种技术方案。

方案实现思路:此时可以评估一下,是否可以通过Hive来进行数据预处理(即通过Hive ETL预先对数据按照**key进行聚合,**或者是预先和其他表进行join),然后在Spark作业中针对的数据源就不是原来的Hive表了,而是预处理后的Hive表。此时由于数据已经预先进行过聚合或join操作了,那么在Spark作业中也就不需要使用原先的shuffle类算子执行这类操作了。

方案实现原理:这种方案从根源上解决了数据倾斜,因为彻底避免了在Spark中执行shuffle类算子,那么肯定就不会有数据倾斜的问题了。但是这里也要提醒一下大家,这种方式属于治标不治本。因为毕竟数据本身就存在分布不均匀的问题,*所以Hive ETL中进行group by或者join等shuffle操作时,还是会出现数据倾斜,导致Hive ETL的速度很慢。*我们只是把数据倾斜的发生提前到了Hive ETL中,避免Spark程序发生数据倾斜而已。

方案优点:实现起来简单便捷,效果还非常好,完全规避掉了数据倾斜,Spark作业的性能会大幅度提升。

方案缺点治标不治本,Hive ETL中还是会发生数据倾斜

方案实践经验:在一些Java系统与Spark结合使用的项目中,会出现Java代码频繁调用Spark作业的场景,而且对Spark作业的执行性能要求很高,就比较适合使用这种方案。

将数据倾斜提前到上游的Hive ETL,每天仅执行一次,只有那一次是比较慢的,而之后每次Java调用Spark作业时,执行速度都会很快,能够提供更好的用户体验。

项目实践经验:有一个交互式用户行为分析系统中使用了这种方案,该系统主要是允许用户通过Java Web系统提交数据分析统计任务,后端通过Java提交Spark作业进行数据分析统计。要求Spark作业速度必须要快,尽量在10分钟以内,否则速度太慢,用户体验会很差。所以我们将有些Spark作业的shuffle操作提前到了Hive ETL中,从而让Spark直接使用预处理的Hive中间表,尽可能地减少Spark的shuffle操作,大幅度提升了性能,将部分作业的性能提升了6倍以上。

2.2、方案二:过滤少数导致倾斜的key

方案适用场景:如果发现导致倾斜的key就少数几个,而且对计算本身的影响并不大的话,那么很适合使用这种方案。比如99%的key就对应10条数据,但是只有一个key对应了100万数据,从而导致了数据倾斜。
  方案实现思路:如果我们判断那少数几个数据量特别多的key,对作业的执行和计算结果不是特别重要的话,那么干脆就直接过滤掉那少数几个key

比如,在Spark SQL中可以使用where子句过滤掉这些key或者在Spar

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值