ツチノコの夢を見ていたツチノコの夢を見ていた

spark.driver.memoryが変わらない

概要

spark.driver.memoryをpythonプログラム内で変えようとしてハマった話。

結論

python module内でsparkをclient modeで動かす際にspark.driver.memoryを変えるには、pysparkのimport前に環境変数のPYSPARK_SUBMIT_ARGSに --conf spark.driver.memory="16g" とオプションを追加する必要がある。16gは適当に所望のメモリサイズを設定する。注意点は、他のオプションのようにSparkConf経由で変えようとしても変更できない点。

詳細

pysparkで以下のようにclient modeでSparkConf経由でdriver.memoryを設定しようと思ってもできなかった。

python
from pyspark import SparkConf
from pyspark.sql import SparkSession
spark = (
	SparkSession.builder
	.config(conf=SparkConf().set("spark.driver.memory", "16g"))
	.enableHiveSupport()
	.getOrCreate()
)

これはSparkConfの設定時点で既にspark JVMが起動しており、client modeではJVMの起動後にdriver.memoryを変更することはできないためとされている。(末尾のリンク参照)

実際にsparkのdocumentにも以下のような記載がある。

Note: In client mode, this config must not be set through the SparkConf directly in your application, because the driver JVM has already started at that point. Instead, please set this through the --driver-memory command line option or in your default properties file.

(ちなみにここら辺はまだちゃんと納得はいっていなくて、具体的にpysparkがJVMを起動しているのはこのあたりで、config反映済みの時点な気がしており、完全な原因究明のためにはもっとpysparkのJVM起動タイミングや設定解決の周りを深掘りする必要がありそう。。。)

とりあえず対症療法にはなってしまうが、この件の解決のためには、JVMの起動の際に --conf spark.driver.memory="16g" というようにオプションを追加する必要がある。これは以下のようにpysparkのimport前に環境変数 PYSPARK_SUBMIT_ARGS にオプションを追加することで可能。

python
import os
os.environ["PYSPARK_SUBMIT_ARGS"] = '--conf spark.driver.memory="16g" pysprk-shell'

from pyspark import SparkConf
from pyspark.sql import SparkSession
spark = (
	SparkSession.builder
	.config(conf=SparkConf().set("spark.driver.memory", "16g"))
	.enableHiveSupport()
	.getOrCreate()
)

参考

https://stackoverflow.com/questions/63283874/spark-java-cannot-change-driver-memory

https://stackoverflow.com/questions/37986963/set-drivers-memory-size-programmatically-in-pyspark