学习一个Spark内存的管理案例
分类: Azure Databricks ◆ 标签: #Azure #Databricks ◆ 发布于: 2023-06-18 19:56:24

在学习Databricks
的内存管理时,我发现在stackoverflow
上有一篇非常好的案例,我总结了一下这个案例并分享给大家。
用户场景
用户在本机写了一个Spark
的应用。这个应用从本地读取14KB的文本文件,读入Spark
之后,然后对这部分数据进行一定的转换操作,最后存储到数据库中。
使用的环境是: 8个Core,16G物理内存。 Java max heap size
被设为了12G.
然后用户使用如下的命令提交任务到Spark
本地执行:
bin/spark-submit --class com.myapp.application --master local[*] --executor-memory 2G --driver-memory 4G /jars/application.jar
然后用户看到Spark
一直输出:
[Executor task launch worker-8hread] WARN org.apache.spark.storage.MemoryStore - Not enough space to cache rdd_57_0 in memory! (computed 26.4 MB so far)
用户很苦恼问题到底在哪里。
解答
解答之前我们先考虑一个知识点,就是如何在Spark
的应用中设置java max heap size
, 我相信一提到这个,大家一定会想起来JVM
的设置参数,例如-Xmx
可以用户设置最大的内存,同时检查Spark
的配置,它有一个参数可以用于传入JVM
的通用设置,这个参数就是spark.executor.extraJavaOptions
, 因此很多人就会想到使用这个参数,传入设置-Xmx, -Xms
来配置java max heap size
, 但是实际上在Spark
这一侧,这是一个错误。
你可以参看Spark
的官方配置文档,这个文档说得特别清楚:
Note that it is illegal to set Spark properties or maximum heap size (-Xmx) settings with this option. Spark properties should be set using a SparkConf object or the spark-defaults.conf file used with the spark-submit script. Maximum heap size settings can be set with spark.executor.memory.
也就是说这么设置是不允许的,Java max Heap Size
是通过spark.executor.memory
来设置的(针对executor), 针对Driver
是通过Spark.driver.memory
来设置的。
回到我们这个用户的案例,这个用户是在本地运行Spark,也就是在非集群模式上运行,这对于学习是可以的,但是有几个点需要注意:
- 在本地模式下是无需使用参数
spark.driver.memory
的。 - 在本地模式下由于worker和
driver
是运行在同一个jvm process
里,因此实际上在本地模式下spark.executor.memory
参数也是没有意义的。 - 在本地模式下应该是使用
spark-shell
而非spark-submit
。
不清楚这个用户是如何设定了java max heap size
到12G的,假定是通过jvm
的运行参数,用户的总共内存才16G, java max heap size = 12G,execute momroy 4 G, 2G设为了driver, 同时通过了spark-submit来提交,这势必导致仅仅只有16G内存的机器在运行Spark应用时,内存不足。
因此最为正确的做法是:
bin/spark-submit --class com.myapp.application --master local[*] /jars/application.jar
本地运行不指定任何参数,就不会有这样的报错了。