Solución:
Dado que está ejecutando Spark en modo local, la configuración spark.executor.memory
no tendrá ningún efecto, como habrás notado. La razón de esto es que el trabajador “vive” dentro del proceso de JVM del controlador que inicia cuando inicia chispa y la memoria predeterminada utilizada para eso es 512M. Puede aumentar eso configurando spark.driver.memory
a algo más alto, por ejemplo 5g. Puede hacerlo de una de las siguientes maneras:
-
configurándolo en el archivo de propiedades (el valor predeterminado es
$SPARK_HOME/conf/spark-defaults.conf
),spark.driver.memory 5g
-
o proporcionando el ajuste de configuración en tiempo de ejecución
$ ./bin/spark-shell --driver-memory 5g
Tenga en cuenta que esto no se puede lograr configurándolo en la aplicación, porque ya es demasiado tarde para entonces, el proceso ya ha comenzado con cierta cantidad de memoria.
La razón por 265,4 MB es que Spark dedica spark.storage.memoryFraction * spark.storage.safetyFraction a la cantidad total de memoria de almacenamiento y por defecto son 0.6 y 0.9.
512 MB * 0.6 * 0.9 ~ 265.4 MB
Por lo tanto, tenga en cuenta que no toda la cantidad de memoria del controlador estará disponible para el almacenamiento RDD.
Pero cuando empiece a ejecutar esto en un clúster, el spark.executor.memory
La configuración se hará cargo al calcular la cantidad para dedicar a la memoria caché de Spark.
También tenga en cuenta que para el modo local debe establecer la cantidad de memoria del controlador antes de iniciar jvm:
bin/spark-submit --driver-memory 2g --class your.class.here app.jar
Esto iniciará la JVM con 2G en lugar del 512M predeterminado.
Detalles aquí:
Para el modo local, solo tiene un ejecutor, y este ejecutor es su controlador, por lo que debe configurar la memoria del controlador. * Dicho esto, en modo local, en el momento en que ejecuta spark-submit, ya se ha lanzado una JVM con la configuración de memoria predeterminada, por lo que configurar “spark.driver.memory” en su configuración no hará nada por usted. En su lugar, debe ejecutar Spark-Submit de la siguiente manera
La respuesta enviada por Grega me ayudó a resolver mi problema. Estoy ejecutando Spark localmente desde un script de Python dentro de un contenedor Docker. Inicialmente recibía un error de memoria insuficiente de Java al procesar algunos datos en Spark. Sin embargo, pude asignar más memoria agregando la siguiente línea a mi script:
conf=SparkConf()
conf.set("spark.driver.memory", "4g")
Aquí hay un ejemplo completo del script de Python que utilizo para iniciar Spark:
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)