我在 Spark 上运行 apache beam 工作负载。我使用 32GB 内存初始化了工作程序(使用 运行从属程序-c 2 -m 32G)。Spark submit 将驱动程序内存设置为 30g,将执行程序内存设置为 16g。但是,执行程序失败java.lang.OutOfMemoryError: Java heap space。
-c 2 -m 32G
java.lang.OutOfMemoryError: Java heap space
master gui 指示每个执行器的内存为 1024M。此外,我看到所有 java 进程都是使用 启动的-Xmx 1024m。这意味着 spark-submit 不会将其执行器设置传播给执行器。
-Xmx 1024m
管道选项如下:
--runner PortableRunner \ --job_endpoint=localhost:8099 \ --environment_type=PROCESS \ --environment_config='{"command": "$HOME/beam/sdks/python/container/build/target/launcher/linux_amd64/boot"}'
作业端点按默认方式设置: docker run --rm --network=host --name spark-jobservice apache/beam_spark_job_server:latest --spark-master-url=spark://$HOSTNAME:7077
docker run --rm --network=host --name spark-jobservice apache/beam_spark_job_server:latest --spark-master-url=spark://$HOSTNAME:7077
如何确保设置传播给执行者?
更新:我将 conf/spark-defaults.conf 设置为
spark.driver.memory 32g spark.executor.memory 32g
并将 conf/spark-env.sh 更改为
SPARK_EXECUTOR_MEMORY=32g
并重新启动集群并重新启动所有内容,执行程序内存仍然限制为 1024M
从你提供的信息来看,你遇到的问题是 Spark 执行器没有正确地接收到所设置的内存配置,这导致了 java.lang.OutOfMemoryError 错误。即使你在 spark-submit 和配置文件中指定了较大的内存限制(如 32GB),执行器似乎仍然以默认的 1GB 内存限制启动。这通常与 Spark 配置项的传播和 Docker 容器的配置有关。
java.lang.OutOfMemoryError
spark-submit
确保 Spark 配置的正确设置: 在你提供的 spark-defaults.conf 和 spark-env.sh 配置中, spark.driver.memory 和 spark.executor.memory 设置应该正确传播给 Spark 运行时。根据你描述的问题,可能是由于环境变量或 Docker 容器设置未正确加载。
spark-defaults.conf
spark-env.sh
spark.driver.memory
spark.executor.memory
检查 spark-submit 命令: 你可以显式地在 spark-submit 命令中指定执行器内存配置。例如:
bash spark-submit \ --class your.main.class \ --master spark://<spark-master>:7077 \ --driver-memory 32g \ --executor-memory 32g \ --conf spark.executor.memory=32g \ --conf spark.driver.memory=32g \ --conf spark.executor.cores=2 \ <your-app-jar>
确保在 spark-submit 命令中明确指定了 --executor-memory 和 --driver-memory。这将覆盖默认的配置,并确保正确传播给执行器。
--executor-memory
--driver-memory
检查 Spark 配置文件: 确保 spark-defaults.conf 中包含以下配置(并且没有注释掉):
ini spark.executor.memory 32g spark.driver.memory 32g
这些设置确保 Spark 通过默认配置传递正确的内存限制。
检查 Docker 配置: 你提到你在使用 Docker 容器来运行 Spark。Docker 容器的资源限制可能会覆盖 Spark 的内存配置。你可以通过以下方式增加 Docker 容器的内存限制:
修改 Docker 运行命令: 如果你是通过 Docker 运行 Spark,可以确保为容器分配足够的内存。使用 docker run 时,确保指定足够的内存和 CPU:
docker run
bash docker run --rm --network=host --name spark-jobservice \ --memory=32g \ --cpus=4 \ apache/beam_spark_job_server:latest \ --spark-master-url=spark://$HOSTNAME:7077
这将为 Docker 容器分配 32GB 内存。
检查 Spark 环境变量: 在 spark-env.sh 中配置 SPARK_EXECUTOR_MEMORY 变量以确保每个执行器的内存大小设置正确。
SPARK_EXECUTOR_MEMORY
bash export SPARK_EXECUTOR_MEMORY=32g export SPARK_DRIVER_MEMORY=32g
然后重新启动集群来确保这些环境变量生效。
-Xmx
bash --conf spark.executor.extraJavaOptions=-Xmx32g
这将强制每个执行器使用 32GB 的堆内存。
验证 Spark UI 配置: 在 Spark UI 中检查执行器的内存分配。确保它们按照你的配置启动,而不是使用默认的 1GB 配置。如果执行器的内存仍然显示为 1GB,那么问题可能与配置的传播有关。
重启 Spark 集群: 配置更改后,确保你重启了 Spark 集群。Spark 的配置文件更改可能需要通过重启 Spark 集群来生效。
spark.executor.extraJavaOptions
这些步骤应该有助于确保内存设置正确传播给 Spark 执行器,并解决 OutOfMemoryError 问题。
OutOfMemoryError