Spark性能调优

executor内存不足

  1. 问题表现1:Container xx is running beyond physical memory limits. Current usage: xxx GB of x GB physical memory used; xx GB of x GB virtual memory used…
    原因:这个报错显而易见,数据使用的内存超过了这个executor分配的内存
  2. 问题表现2:长时间的 Fail to get RpcResponse: Timeout,最后会报heartbeat心跳检测失败而任务失败
    原因:实际上同样是因为内存不足,导致GC而超时,最终失败

解决:
1 首先可以尝试开大executor的内存分配
2 如果配置的内存无法满足数据内存,可以尝试:
2.1 增加大数据量位置的repartition数

   val allDf = sourceDf
      .repartition(5000)
      .flatMap(row => { }).toDF()

2.2 增加spark session的超时时间

    val ss = SparkSession.builder()
      .config("spark.sql.shuffle.partitions", 1000)
      .config("spark.driver.maxResultSize", "20g")
      .config("hive.exec.dynamic.partition", true)
      .config("hive.exec.dynamic.partition.mode", "nonstrict")
      .config("hive.exec.parallel", true)
      .config("mapred.max.split.size", 64000000)
      .config("mapred.min.split.size.per.node", 64000000)
      .config("mapred.min.split.size.per.rack", 64000000)
      .config("hive.exec.reducers.bytes.per.reducer", 256000000)
      .config("hive.exec.reducers.max", 2000)
      .config("hive.merge.mapredfiles", true)
      .config("hive.merge.smallfiles.avgsize", 128000000)
      .config("hive.merge.size.per.task", 128000000)
      .config("spark.yarn.executor.memoryOverhead", "10g")
      .config("spark.network.timeout", 10000000)	// 调大
      .enableHiveSupport()
      .getOrCreate()

GC overhead limit exceeded

executor报错:

 java.lang.OutOfMemoryError: GC overhead limit exceeded

错误表明JVM花费了太多时间(默认是98%)来回收很少的内存(默认是2%),并且这种情况持续了很长时间。这通常是因为堆内存(Heap)太小,无法容纳应用程序的内存需求,或者是因为内存泄漏。

解决方案

  1. 增加 Executor 内存: 在提交 Spark 作业时,可以通过 --executor-memory 或在 Spark 配置文件中设置 spark.executor.memory 来增加每个 Executor 的内存大小。例如,将 Executor 内存增加到 8G:
spark-submit --executor-memory 8g ...

或在配置文件中:

spark.executor.memory=8g
  1. 增加堆外内存(Off-Heap Memory): 如果已经增加了堆内存但问题仍然存在,可以考虑使用堆外内存。通过设置 spark.executor.memoryOverhead,可以为每个 Executor 分配额外的堆外内存。例如,分配 1G 堆外内存:
spark.executor.memoryOverhead=1024
  1. 优化垃圾回收: 调整垃圾回收器的设置可能有助于减少 GC 的开销。例如,使用 G1 垃圾回收器替代默认的垃圾回收器。可以通过设置 spark.executor.extraJavaOptions 来调整:
spark.executor.extraJavaOptions=-XX:+UseG1GC
  1. 减少数据倾斜: 数据倾斜可能导致某些 Executor 需要处理比其他 Executor 更多的数据,从而增加内存压力。通过重新分区或使用 Spark 的高级功能(如 salting)来减少数据倾斜。

  2. 优化 Spark 应用程序:

    • 减少不必要的数据缓存
    • 使用更高效的数据结构
    • 避免在单个大对象上操作,尽可能分解成小对象处理。
  3. 调整 GC 配置: 如果 GC 开销过高,可以尝试调整 GC 相关参数,例如增加 GC 线程数,调整堆区大小等。这需要对 JVM 的垃圾回收机制有一定了解。

UNION ALL代替UNION

UNION会默认对两个表的结果进行去重,如果没有去重的需要,就使用UNION ALL,速度会更快

persist与耗时监控

在主流程的对运算结果调用处persist,并打点进行耗时监控。而不是在运算方法内部persist,便于看清每一步的运算时间。

用OR替换UNION ALL

UNION ALL 操作会消耗大量的内存和CPU,如果可能,尽量减少使用。在这个查询中,你可以尝试将三个 UNION ALL 的查询合并为一个,使用 OR 条件来替代。

用JOIN替换IN

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值