我试图诊断由Spark执行器引起的OutOfMemoryError,希望有人能在这里帮助我。
配置
我在我的Windows机器上以本地模式运行Spark(3.1.3)。我的JVM示例设置为2g内存。我的Spark执行器内存为1g(spark.executor.memory
)。
场景
我只是对本地文件系统中的一些parquet文件运行了一个Spark SQL查询。我想测试我们系统的其他部分,看看它如何处理一个超长记录(行),所以我给出了一个Spark SQL查询,如下所示:
SELECT repeat('A', 50000000) AS test
字符串
当我运行这个查询并写入一个csv文件时,JVM进程崩溃了,出现java.lang.OutOfMemoryError:Java堆空间
问题
据我所知,输入数据大约是50 MB(5000万个字符),这应该比配置的执行器内存空间(1g)小得多。
我检查了堆转储,确实看到了这个char数组的许多副本,导致大约800 MB的内存使用。
但是,如果我使用一个不同的查询,输入更大(比如200 MB),但不是这么大的行,那就没问题了。
Spark一张唱片拷贝这么多份正常吗?有什么办法可以避免这种OOM吗?谢谢
参考资料
以下是例外的一部分:
Thread 'Executor task launch worker for task 0.0 in stage 6.0 (TID 35)' with ID = 135
java.lang.OutOfMemoryError.<init>(OutOfMemoryError.java:48)
java.util.Arrays.copyOf(Arrays.java:3332)
com.univocity.parsers.common.input.ExpandingCharAppender.expand(ExpandingCharAppender.java:115)
com.univocity.parsers.common.input.ExpandingCharAppender.expand(ExpandingCharAppender.java:123)
com.univocity.parsers.common.input.ExpandingCharAppender.append(ExpandingCharAppender.java:207)
com.univocity.parsers.csv.CsvWriter.append(CsvWriter.java:405)
com.univocity.parsers.csv.CsvWriter.processRow(CsvWriter.java:228)
com.univocity.parsers.common.AbstractWriter.submitRow(AbstractWriter.java:352)
com.univocity.parsers.common.AbstractWriter.writeRow(AbstractWriter.java:830)
org.apache.spark.sql.catalyst.csv.UnivocityGenerator.write(UnivocityGenerator.scala:94)
org.apache.spark.sql.execution.datasources.csv.CsvOutputWriter.write(CsvOutputWriter.scala:46)
org.apache.spark.sql.execution.datasources.SingleDirectoryDataWriter.write(FileFormatDataWriter.scala:140)
型
我试过阅读Spark内存管理,但仍然可以找到相关的材料。我试过缓存数据,并将数据只持久化在磁盘上,但没有任何帮助。
1条答案
按热度按时间ymzxtsji1#
从你的描述中,你似乎是在单JVM模式下运行Spark,这是 * 本地 * 模式,而不是 * 独立 *,这实际上是一个集群运行时。
在本地模式下,不使用执行器设置,您需要使用
spark.driver.memory=2g
config或--driver-memory 2g
spark-submit参数指定驱动程序的内存需求。