背景:
我正在跑一个数据处理较为复杂的程序。然后调试了很多遍,出现了GC问题,如下图bug.
GC overhead limit exceeded-这个bug错误通常表示 Java 虚拟机 (JVM) 在进行垃圾回收时花费了过多的时间,并且回收的内存量非常少。这通常是由于内存不足或数据量过大导致的,如下图,我自己跑的程序出现错误。
尝试以下解决方案
1. 增加 Executor 内存
增加 Spark Executor 的内存在创建 SparkSes,sion
时设置 spark.executor.memory
参数:
val spark = SparkSession.builder()
.appName("xxxxx")
.config("spark.executor.memory", "20g")
.config("spark.kryoserializer.buffer.max", "512m")
.config("spark.serializer", "org.20apache.spark.serializer.KryoSerializer")
.getOrCreate()
2. 增加 Driver 内存
增加 Driver 的内存:
val spark = SparkSession.builder() .appName("xxxxx")
.config("spark.driver.memory", "8g")
.config("spark.executor.memory", "20g")
.config("spark.kryoserializer.buffer.max", "512m")
.config("spark.serializer", "org.apache.spark.serializer.KryoSerializer")
.getOrCreate()
3. 调整分区数量
增加数据的分区数量可以帮助分散数据处理的负担,从而减少每个分区的内存消耗。
使用 repartition()
或 coalesce()
方法来调整 DataFrame 的分区:
val numPartitions = 200 // 我差不多几十个G数据,
val repartitionedDF = userInfoDF.repartition(numPartitions)
4. 调整 Spark 配置参数
调整以下 Spark 配置参数:
.config("spark.memory.fraction", "0.7") // 调整内存比例
.config("spark.memory.storageFraction", "0.5") // 调整存储比例
基本就这几种方案,一个一个试出来的,然后解决了,遇事不决调整资源,然后调整比例。最重要的是内存!!内存,还是TMD内存!!!
非常完美!