spark 出现OOM内存溢出问题,但不想调大executor的内存,以当前内存甚至更小内存把任务运行下去的方法

法一:增加单个task的内存使用量

增加最大 Heap值,即上图中 M2 的值,使每个 Task 可使用内存增加。

降低 Executor 的可用 Core 的数量 N , 使 Executor 中同时运行的任务数减少,在总资源不变的情况下,使每个 Task 获得的内存相对增加。当然,这会使得 Executor 的并行度下降。可以通过调高 spark.executor.instances 参数来申请更多的 executor 实例(或者通过 

spark.dynamicAllocation.enabled 启动动态分配),提高job的总并行度。

法二:降低单个Task的内存消耗量

降低单个Task的内存消耗量可从配置方式和调整应用逻辑两个层面进行优化:

  • 配置方式

    减少每个 Task 处理的数据量,可降低 Task 的内存开销,在 Spark 中,每个 partition 对应一个处理任务 Task,因此,在数据总量一定的前提下,可以通过增加 partition 数量的方式来减少每个 Task 处理的数据量,从而降低 Task 的内存开销。针对不同的 Spark 应用类型,存在不同的 partition 配置参数 :

 
  1. P = spark.default.parallism (非SQL应用)

  2. P = spark.sql.shuffle.partition (SQL 应用)

通过增加 P 的值,可在一定程度上使 Task 现有内存满足任务运行。注: 当调整一个参数不能解决问题时,上述方案应进行协同调整。

又或者在代码中repartition设置分区数

法三:通过spark ui查看各个task的数据量(shuffle read 和shuffle write),看看是否出现数据倾斜

数据倾斜的解决方案

1、当某些key的数据量非常大时,可以在map阶段先把数据打乱(给key加上随机数前缀,比如0~10的随机前缀,就可以把一个key的数据分成十份放到不同分区中了),

然后再根据这种key 再shuffle随机到不同的分区。然后对这些加了前缀的key进行部分聚合,部分聚合完成后,再去除随机加的key的前缀,然后再把前面部分聚合的数据进行合并。

ps:这个原理是hive 中关于group by的一个优化参数hive.groupby.skewindata,原理和上述差不多。在尚硅谷的学习资料中知道的。原话如下:
 

当选项设定为 true,生成的查询计划会有两个 MR Job。

第一个 MR Job 中,Map 的输 出结果会随机分布到 Reduce 中,每个 Reduce 做部分聚合操作,并输出结果,

这样处理的结 果是相同的 Group By Key 有可能被分发到不同的 Reduce 中,从而达到负载均衡的目的;

第 二个 MR Job 再根据预处理的数据结果按照 Group By Key 分布到 Reduce 中(这个过程可以 保证相同的 Group By Key 被分布到同一个 Reduce 中),

最后完成最终的聚合操作。

 

2、

可以把出现数据倾斜的那些key给先提前筛选出来,在代码中以硬编码的形式把这些数据过滤掉,这样当前任务就可以以低成本的方式处理这部分数据了。

(这样的话,这个任务在并行度不变的情况下,但每个executor的内存可以不用根据倾斜的那部分数据设置内存上限,使得内存利用率提高)

而那些被过滤掉的会导致数据倾斜的数据,再使用另一个任务专门进行处理。此时可以把executor的内存调高,但executor/core就不需要那么高了,因为只有少部分key,并行度要求不高。(或许这部分数据也可以参考1中的方式)

 

 

总结,我觉得处理数据倾斜的方式还是优先使用第1的方式,只不过代码多写几行而已。。可以提高内存利用率,并且后期不需要再麻烦的修改。第2的方式,硬编码是真的不推荐。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值