Spark 超大数据量下OOM的解决

7 篇文章 0 订阅
4 篇文章 0 订阅

背景

大表2T,小表 30G+,两表join到一新表分区。

要求: 尽可能的少用executor core和memory,并减少时间占用

前提

executor core和memory占用已经够高(--num-executors 200 --executor-cores 4 --executor-memory 30G ),不能再添加过多了。

executor内存 集群统一配置的上限是:yarn.scheduler.maximum-allocation-mb = 30G,

所以 针对spark常见的优化——“把小变量广播出去”变的不太可行。广播的内容会存在每一个executor内,那内存都被广播占满了。

已经做过的优化:

  • “尽量避免频繁new新的rdd对象”

  • “用reduceBy代替groupBy 的shuffle算子”

在处理过程中,频繁遇到了oom报错的问题

现象

显然GC时间过久,这还是在使用了reduceByKey的情况下

executors内报错

CoarseGrainedExecutorBackend: RECEIVED SIGNAL TERM 可以通过配置关闭动态分配

--conf spark.dynamicAllocation.enabled=false

日志里原因: jvm 堆OOM 了

解决方案

1 调低为spark缓存保留的内存占比 和 executor里的核数

广义上讲,spark Executor JVM内存可以分为两部分。Spark memory 和 User memory。这由属性spark.memory.fraction 控制 ,他的值介于 0 和 1 之间, 默认为0.6。

在 spark 应用程序中处理图像或进行内存密集型处理时,请考虑减少spark.memory.fraction. 这将为您的应用程序工作提供更多内存。Spark 可以溢出,所以它仍然可以使用较少的内存共享。

问题的第二部分是work的划分。如果可能,将数据分成更小的块。较小的数据可能需要较少的内存。但如果那是不可能的,那么你就是在牺牲计算来换取内存。通常,单个执行程序将运行多个内核。执行器的总内存必须足以处理所有并发任务的内存需求。如果增加执行程序内存不是一个选项,您可以减少每个执行程序的核心数,以便每个任务获得更多内存来使用。使用 1 个核心执行程序进行测试,这些执行程序具有您可以提供的最大可能内存,然后不断增加核心,直到找到最佳核心数

(--num-executors 200 --executor-cores 4 --executor-memory 30G )

2 调整 driver和executor的 spark.yarn.executor.memoryOverhead,提高稳定性

在 YARN,K8S 部署模式下,container 会预留一部分内存,形式是堆外,用来保证稳定性,主要存储nio buffer,函数栈等一些开销。

这部分内存,你不用管堆外还是堆内,开发者用不到,spark也用不到,

所以不用关心,千万不指望调这个参数去提升性能,它的目的是保持运行时的稳定性。

3 添加堆外内存: spark.memory.offHeap.size

作为一个 JVM 进程,Executor 的内存管理建立在 JVM 的内存管理之上,Spark 对 JVM 的堆内(On-heap)空间进行了更为详细的分配,以充分利用内存。同时,Spark 引入了堆外(Off-heap)内存,使之可以直接在工作节点的系统内存中开辟空间,进一步优化了内存的使用。

在默认情况下堆外内存并不启用,可通过配置 spark.memory.offHeap.enabled 参数启用,并由 spark.memory.offHeap.size 参数设定堆外空间的大小。

4 调整driver 的 Xmx 堆 和 Xms 堆

调大driver的内存(Xmx)

修改集群的配置文件 spark-defaults.conf文件

spark.driver.memory              30g

或者直接在spark-submit命令里修改

--driver-memory 30G

这个值默认是1G,即使改大了也不会生效。 SPARK_DRIVER_MEMORY 只设置了 Xmx heap(堆)。初始堆大小保持为 1G,并且堆的大小永远不会扩展到 Xmx 堆。

修改Xms

你有没有转储你的master gc日志?所以我遇到了类似的问题,我发现 SPARK_DRIVER_MEMORY 只设置了 Xmx heap(堆)。初始堆大小保持为 1G,并且堆的大小永远不会扩展到 Xmx 堆。

使用如下配置就看生效了

--conf spark.driver.extraJavaOptions=-Xms10g

ps aux | grep java 你将会看到如下的日志:=

24501 30.7 1.7 41782944 2318184 pts/0 Sl+ 18:49 0:33 /usr/java/latest/bin/java -cp /opt/spark/conf/:/opt/spark/jars/* -Xmx30g -Xms10g

添加配置如下:

--conf spark.dynamicAllocation.enabled=false --conf spark.core.connection.ack.wait.timeout=300
--conf spark.storage.memoryFraction=0.5 --conf spark.shuffle.memoryFraction=0.3
--conf spark.yarn.driver.memoryOverhead=3072 --conf spark.executor.memoryOverhead=3072
--conf spark.memory.offHeap.enabled=true --conf spark.memory.offHeap.size=8g
--conf spark.driver.extraJavaOptions=-Xms20g

参考

https://spark.apache.org/docs/latest/cluster-overview.html

https://www.cnblogs.com/frankdeng/p/9301783.html

https://stackoverflow.com/questions/21138751/spark-java-lang-outofmemoryerror-java-heap-space

https://www.jianshu.com/p/391f8776e66f

https://blog.csdn.net/u012811805/article/details/104745457/

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值