Spark: Container killed by YARN for exceeding memory limits 问题的解决

问题背景

Spark 1.6.0

具体业务场景不谈,技术向描述是:
该流程每天会通过调度系统启动一个 k8s pod 并执行镜像中的 python 代码和 hive on spark 的任务,但近期非常不稳定,流程报错频繁。
观察日志及 sparkUI 的执行进度,是在 hive on spark 环节,出现了“Container killed by YARN for exceeding memory limits” 的情况。
在这里插入图片描述

问题分析

镜像内容没变,变的是数据。询问数据来源,也得到了近期数据量增大的回复。
由上图可知,问题出现在 Executor 收到的数据量已大于该 Executor 的内存值,造成了 Spark 语境下常见的 OOM 问题。

盲目调参事倍功半,停一下,从头理一下到 Executor 要处理的数据是怎么来的。
Spark 中,数据被抽象成了 RDD,RDD 中的数据是分区的,在执行过程中,RDD 的每个分区将会派给每个 Executor 中的每个 core 去计算。
那么现在问题就是,上游 RDD 中的数据变多了,在分区数不增加的情况下,RDD 每个分区中的数据就增多了,那么发往下游 Executor 中的数据就在增多,就超过了 Executor 的内存上限。

例:之前一个 Executor 内存 20g,预留内存 1g,设置了 4 个 core,接收了 4 个 RDD 分区,4 个分区数据加起来 18g,但是现在上游 RDD 分区数据增加,4 个分区增加到 22g,如果该 Executor 还是 4 个 core,接收 4 个分区,那么就 cover 不住了,就造成了 OOM 。

结论

  • 增大 Executor 的内存:spark.executor.memory。
  • 增大 Executor 的预留内存:spark.yarn.executor.memoryOverhead(2.3-)、spark.executor.memoryOverhead(2.3+)
  • 要注意,spark on yarn 部署模式下:Executor 在 container 中执行,所以 spark.executor.memory + spark.yarn.executor.memoryOverhead 的值不可超过 container 的内存值:yarn.scheduler.maximum-allocation-mb ,否则直接被 kill。
  • 降低 Executor 的 core 数,直接结果是同一时刻发到 Executor 中的分区减少了(那么数据就减少了),用牺牲效率的方式换取稳定。
  • 增加 RDD 的分区数,使每个分区内的数据减少,那么在不调整 Executor 内 core 数量的情况下,Executor 内的数据总量就少了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值