记一次pyspark数据倾斜引起OOM的解决方案

1.报错信息

pyspark脚本在自动调度过程中,报错内存溢出。beyond the ‘PHYSICAL’ memory limit. Current usage: 11.0 GB of 11 GB physical memory used。

CONSOLE# 2023-05-06 06:13:05,368 | ERROR | main | Application diagnostics message: Application application_1682198688166_1065397 failed 2 times due to AM Container for appattempt_1682198688166_1065397_000002 exited with exitCode: -104

CONSOLE# Failing this attempt.Diagnostics: [2023-05-06 06:13:02.276]Container [pid=8224,containerID=container_e21_1682198688166_1065397_02_000001] is running 19828736B beyond the 'PHYSICAL' memory limit. Current usage: 11.0 GB of 11 GB physical memory used; 18.1 GB of 165 GB virtual memory used. Killing container.

2.问题分析

2.1 增加资源

从报错信息可以初步定位是数据大小超出了内存限制,可以通过加大资源(eg: driver memory)解决,但是盲目加大资源并不是很好的解决方案,过一段时间可能又会超出内存限制。

2.2 增大并行度

除了加大资源外,数据倾斜也会引起的某一分区数据量过大,导致OOM。因此,通过加大spark并行度也可以解决此问题。
首先,观察spark数据各个分区的数据量并画直方图:

from pyspark.sql import functions as fn
# 输出分区数量
print(df.rdd.getNumPartitions())
# fn.spark_partition_id():pyspark内置函数,可以获取各个分区id
pdf = df.groupBy(fn.spark_partition_id()).count().toPandas()
pdf[['count']].plot(kind='hist')

在这里插入图片描述
可以看到各个分区的数据量呈长尾分布,大部分分区数据量在5000条记录左右,有少部分分区记录数超过2万,因此数据量较大的分区容易出现OOM问题。
然后增大并行度:

df=df.repartition(800)

再次观察各个分区数据量的直方图:
在这里插入图片描述
可以看到各个分区数据量呈正态分布,且不存在数据量很大的分区。
再次运行pyspark程序也能正常运行,不会出现OOM问题。

3. 数据倾斜解决方案总结

网上有资料推荐使用spark.default.parallelism=800参数增加spark的默认并行度,但是实测并没有效果。经过查阅,发现spark官网关于spark.default.parallelism参数有以下说明:
1、对于reduceByKey和join这些分布式shuffle算子操作,取决于它的父RDD中分区数的最大值
2、对于没有父RDD的的算子,比如parallelize,依赖于集群管理器
且spark.default.parallelism是针对rdd的shuffle操作的默认并行度。因此更推荐使用repartition操作增加并行度。
除了增加并行度外,还有其他方式解决或缓解数据倾斜问题,如hive ETL分区分桶、两阶段聚合、map join等操作,但是repartition通常是是最简单且有效的方案,推荐第一时间尝试。
值得注意的是,并行度也不可盲目增大, 并行度增加也会带来启动task的资源消耗,带来性能下降。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

贝塔西塔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值