如何设置 Apache Spark Executor 内存
Posted
技术标签:
【中文标题】如何设置 Apache Spark Executor 内存【英文标题】:How to set Apache Spark Executor memory 【发布时间】:2014-12-21 02:59:36 【问题描述】:如何增加 Apache spark 执行器节点的可用内存?
我有一个适合加载到 Apache Spark 的 2 GB 文件。我目前在一台机器上运行 apache spark,所以驱动程序和执行程序在同一台机器上。机器有 8 GB 内存。
当我将文件设置为缓存在内存中后尝试计算文件的行数时,出现以下错误:
2014-10-25 22:25:12 WARN CacheManager:71 - Not enough space to cache partition rdd_1_1 in memory! Free memory is 278099801 bytes.
我查看了文档here,并将$SPARK_HOME/conf/spark-defaults.conf
中的spark.executor.memory
设置为4g
UI 显示此变量已在 Spark 环境中设置。你可以找到截图here
但是,当我转到 Executor tab 时,我的单个 Executor 的内存限制仍设置为 265.4 MB。我也仍然遇到同样的错误。
我尝试了here 提到的各种方法,但我仍然收到错误消息,并且不知道应该在哪里更改设置。
我正在从 spark-shell 交互地运行我的代码
【问题讨论】:
【参考方案1】:由于您在本地模式下运行 Spark,因此设置 spark.executor.memory
不会产生任何影响,正如您所注意到的。原因是 Worker “存在”在您启动 spark-shell 时启动的驱动程序 JVM 进程中,并且用于此的默认内存为 512M。您可以通过将 spark.driver.memory
设置为更高的值来增加它,例如 5g。你可以这样做:
在属性文件中设置(默认为$SPARK_HOME/conf/spark-defaults.conf
),
spark.driver.memory 5g
或通过在运行时提供配置设置
$ ./bin/spark-shell --driver-memory 5g
请注意,这不能通过在应用程序中设置来实现,因为到那时已经太晚了,进程已经启动了一些内存。
265.4 MB的原因是Sparkdedicates spark.storage.memoryFraction * spark.storage.safetyFraction占存储内存总量,默认为0.6和0.9。
512 MB * 0.6 * 0.9 ~ 265.4 MB
因此请注意,并非所有驱动程序内存都可用于 RDD 存储。
但是当您开始在集群上运行它时,spark.executor.memory
设置将在计算专用于 Spark 内存缓存的数量时接管。
【讨论】:
5g 等于 5Gb 吗? @Chuck spark.apache.org/docs/latest/… "驱动进程使用的内存量,即初始化 SparkContext 的位置,格式与 JVM 内存字符串相同,带有大小单位后缀("k"、"m "、"g" 或 "t")(例如 512m、2g)。" 我正在使用IDEA运行spark程序,我没有自己安装spark。我不知道 SPARK_HOME 在哪里【参考方案2】:另请注意,对于本地模式,您必须在启动 jvm 之前设置驱动程序内存量:
bin/spark-submit --driver-memory 2g --class your.class.here app.jar
这将以 2G 而不是默认的 512M 启动 JVM。 详情here:
对于本地模式,你只有一个执行器,这个执行器就是你的驱动程序,所以你需要设置驱动程序的内存。 *也就是说,在本地模式下,当您运行 spark-submit 时,已经使用默认内存设置启动了 JVM,因此在您的 conf 中设置“spark.driver.memory”实际上不会为您做任何事情。相反,您需要按如下方式运行 spark-submit
【讨论】:
【参考方案3】:Grega 提交的答案帮助我解决了我的问题。我从 Docker 容器内的 python 脚本本地运行 Spark。最初,在 Spark 中处理一些数据时,我遇到了 Java 内存不足错误。但是,我可以通过在脚本中添加以下行来分配更多内存:
conf=SparkConf()
conf.set("spark.driver.memory", "4g")
这是我用来启动 Spark 的 Python 脚本的完整示例:
import os
import sys
import glob
spark_home = '<DIRECTORY WHERE SPARK FILES EXIST>/spark-2.0.0-bin-hadoop2.7/'
driver_home = '<DIRECTORY WHERE DRIVERS EXIST>'
if 'SPARK_HOME' not in os.environ:
os.environ['SPARK_HOME'] = spark_home
SPARK_HOME = os.environ['SPARK_HOME']
sys.path.insert(0,os.path.join(SPARK_HOME,"python"))
for lib in glob.glob(os.path.join(SPARK_HOME, "python", "lib", "*.zip")):
sys.path.insert(0,lib);
from pyspark import SparkContext
from pyspark import SparkConf
from pyspark.sql import SQLContext
conf=SparkConf()
conf.set("spark.executor.memory", "4g")
conf.set("spark.driver.memory", "4g")
conf.set("spark.cores.max", "2")
conf.set("spark.driver.extraClassPath",
driver_home+'/jdbc/postgresql-9.4-1201-jdbc41.jar:'\
+driver_home+'/jdbc/clickhouse-jdbc-0.1.52.jar:'\
+driver_home+'/mongo/mongo-spark-connector_2.11-2.2.3.jar:'\
+driver_home+'/mongo/mongo-java-driver-3.8.0.jar')
sc = SparkContext.getOrCreate(conf)
spark = SQLContext(sc)
【讨论】:
【参考方案4】:显然,这个问题从来没有说在本地模式下运行而不是在纱线上。不知何故,我无法让 spark-default.conf 更改工作。相反,我尝试了这个,它对我有用
bin/spark-shell --master yarn --num-executors 6 --driver-memory 5g --executor-memory 7g
(无法将执行程序内存增加到 8g,纱线配置有一些限制。)
【讨论】:
OP 确实提到他使用的是单台机器。 你让executor-memory
高于driver-memory
?【参考方案5】:
你需要增加驱动内存。在mac上(即在本地master上运行时),默认驱动内存为1024M)。默认情况下,380Mb 分配给执行者。
在增加 [--driver-memory 2G] 后,执行程序内存增加到 ~950Mb。
【讨论】:
【参考方案6】:据我所知,在运行时无法更改 spark.executor.memory
。如果您正在运行带有 pyspark 和 graphframes 的独立版本,则可以通过执行以下命令来启动 pyspark REPL
:
pyspark --driver-memory 2g --executor-memory 6g --packages graphframes:graphframes:0.7.0-spark2.4-s_2.11
请务必根据最新发布的 Spark 版本适当更改 SPARK_VERSION
环境变量
【讨论】:
【参考方案7】:在 spark/conf 目录中创建一个名为 spark-env.sh 的文件,然后 添加这一行
SPARK_EXECUTOR_MEMORY=2000m #memory size which you want to allocate for the executor
【讨论】:
没错,我使用具体配置运行主控,每次运行 spark 命令时都不需要添加选项。但这仅适用于集群节点,如果它是独立的,则设置为SPARK_WORKER_MEMORY
。【参考方案8】:
spark-submit \
--class org.apache.spark.examples.SparkPi \
--master yarn \
--deploy-mode cluster \ # can be client for client mode
--executor-memory 2G \
--num-executors 5 \
/path/to/examples.jar \
1000
【讨论】:
【参考方案9】:您可以使用以下示例构建命令
spark-submit --jars /usr/share/java/postgresql-jdbc.jar --class com.examples.WordCount3 /home/vaquarkhan/spark-scala-maven-project-0.0.1-SNAPSHOT.jar --jar --num-executors 3 --driver-memory 10g **--executor-memory 10g** --executor-cores 1 --master local --deploy-mode client --name wordcount3 --conf "spark.app.id=wordcount"
【讨论】:
【参考方案10】:根据驱动程序给出的指令运行 Spark 任务需要 Spark 执行器内存。基本上,它需要更多资源,具体取决于您提交的作业。
Executor 内存包括执行任务所需的内存加上开销内存,不应大于 JVM 的大小和 yarn 最大容器大小。
在spark-defaults.conf中添加如下参数
spar.executor.cores=1
spark.executor.memory=2g
如果您使用任何集群管理工具,如 cloudera manager 或 amabari,请刷新集群配置,以便将最新配置反映到集群中的所有节点。
或者,我们可以在运行spark-submit
命令以及类和应用程序路径时将执行程序核心和内存值作为参数传递。
例子:
spark-submit \
--class org.apache.spark.examples.SparkPi \
--master yarn \
--deploy-mode cluster \ # can be client for client mode
--executor-memory 2G \
--num-executors 5 \
/path/to/examples.jar \
1000
【讨论】:
【参考方案11】:您提到您在 spark-shell 上以交互方式运行您的代码,因此,如果没有为驱动程序内存或执行程序内存设置适当的值,那么 spark 默认为它分配一些值,这是基于它的属性文件(其中提到了默认值)。
我希望你知道有一个驱动程序(主节点)和一个工作节点(执行程序被创建和处理的地方),所以基本上火花程序需要两种类型的空间,所以如果你想在启动 spark-shell 时设置驱动内存。
spark-shell --driver-memory "your value" 并设置执行器内存: spark-shell --executor-memory "你的价值"
那么我认为你最好使用你希望你的 spark-shell 使用的内存的期望值。
【讨论】:
【参考方案12】:在 Windows 或 Linux 中,您可以使用以下命令:
spark-shell --driver-memory 2G
【讨论】:
【参考方案13】:用于为执行程序配置核心和内存。
spark-shell --help
--master MASTER_URL spark://host:port, mesos://host:port, yarn,
--executor-memory MEM Memory per executor (e.g. 1000M, 2G) (Default: 1G).
--total-executor-cores NUM Total cores for all executors.
--executor-cores NUM Number of cores used by each executor. (Default: 1 in YARN and K8S modes, or all available cores on the worker in standalone mode).
如果您的系统有 6 个内核和 6GB RAM,请选择以下命令之一:
-
创建 6 个执行程序,每个执行程序具有 1 个核心和 1GB RAM
spark-shell --master spark://sparkmaster:7077 --executor-cores 1 --executor-memory 1g
-
创建 3 个执行程序,每个执行程序具有 1 个核心和 2GB RAM。最大内存为 6GB,3 核是理想的。
spark-shell --master spark://sparkmaster:7077 --executor-cores 1 --executor-memory 2g
-
创建 2 个执行程序,每个执行程序具有 3 个内核和 3GB RAM。使用所有 RAM 和内核
spark-shell --master spark://sparkmaster:7077 --executor-cores 3 --executor-memory 3g
-
创建 2 个执行程序,每个执行程序具有 3 个内核,并且只有 1GB RAM。
spark-shell --master spark://sparkmaster:7077 --executor-cores 3 --executor-memory 1g
-
如果我们只想使用一个具有 1 个核心和 1GB RAM 的执行器
spark-shell --master spark://sparkmaster:7077 --total-executor-cores 1 --executor-cores 1 --executor-memory 1g
-
如果我们只想使用两个 executor,每个 1 core 和 1GB RAM
spark-shell --master spark://sparkmaster:7077 --total-executor-cores 2 --executor-cores 1 --executor-memory 1g
-
如果我们只想使用两个执行器,每个执行器有 2 个内核和 2GB RAM(总共 4 个内核和 4GB RAM)
spark-shell --master spark://sparkmaster:7077 --total-executor-cores 4 --executor-cores 2 --executor-memory 2g
-
如果我们应用 --total-executor-cores 2,那么只会创建一个执行器。
spark-shell --master spark://sparkmaster:7077 --total-executor-cores 4 --executor-cores 2 --executor-memory 2g
-
总执行器核心数:3 不能被每个执行器的核心数整除:2,剩下的核心数:1 将不会被分配。将创建一个具有 2 个核心的执行器。
spark-shell --master spark://sparkmaster:7077 --total-executor-cores 3 --executor-cores 2 --executor-memory 2g
所以--total-executor-cores
/ --executor-cores
= 将创建的执行者数量。
【讨论】:
以上是关于如何设置 Apache Spark Executor 内存的主要内容,如果未能解决你的问题,请参考以下文章
如何确保我的 Apache Spark 设置代码只运行一次?
在Apache Spark中使用Bigquery Connector时如何设置分区数?