Mi clúster: 1 maestro, 11 esclavos, cada nodo tiene 6 GB de memoria.
Mi configuración:
spark.executor.memory=4g, Dspark.akka.frameSize=512
Aquí está el problema:
Primero , leí algunos datos (2,19 GB) de HDFS a RDD:
val imageBundleRDD = sc.newAPIHadoopFile(...)
En segundo lugar , haga algo en este RDD:
val res = imageBundleRDD.map(data => {
val desPoints = threeDReconstruction(data._2, bg)
(data._1, desPoints)
})
Por último , salida a HDFS:
res.saveAsNewAPIHadoopFile(...)
Cuando ejecuto mi programa muestra:
.....
14/01/15 21:42:27 INFO cluster.ClusterTaskSetManager: Starting task 1.0:24 as TID 33 on executor 9: Salve7.Hadoop (NODE_LOCAL)
14/01/15 21:42:27 INFO cluster.ClusterTaskSetManager: Serialized task 1.0:24 as 30618515 bytes in 210 ms
14/01/15 21:42:27 INFO cluster.ClusterTaskSetManager: Starting task 1.0:36 as TID 34 on executor 2: Salve11.Hadoop (NODE_LOCAL)
14/01/15 21:42:28 INFO cluster.ClusterTaskSetManager: Serialized task 1.0:36 as 30618515 bytes in 449 ms
14/01/15 21:42:28 INFO cluster.ClusterTaskSetManager: Starting task 1.0:32 as TID 35 on executor 7: Salve4.Hadoop (NODE_LOCAL)
Uncaught error from thread [spark-akka.actor.default-dispatcher-3] shutting down JVM since 'akka.jvm-exit-on-fatal-error' is enabled for ActorSystem[spark]
java.lang.OutOfMemoryError: Java heap space
Hay demasiadas tareas?
PD : Todo está bien cuando los datos de entrada son de aproximadamente 225 MB.
¿Como puedó resolver esté problema?
out-of-memory
apache-spark
hequn8128
fuente
fuente
Respuestas:
Tengo algunas sugerencias:
spark.executor.memory=6g
. Asegúrese de estar usando la mayor cantidad de memoria posible verificando la interfaz de usuario (le dirá la cantidad de memoria que está usando)spark.storage.memoryFraction
. Si no usacache()
opersist
en su código, este también podría ser 0. Su valor predeterminado es 0.6, lo que significa que solo obtiene 0.4 * 4g de memoria para su montón. El IME que reduce la fracción de membranas a menudo hace que las OOM desaparezcan. ACTUALIZACIÓN: desde spark 1.6 aparentemente ya no necesitaremos jugar con estos valores, spark los determinará automáticamente.String
estructuras muy anidadas (Map
clases de casos similares y anidadas). Si es posible, intente usar solo tipos primitivos e indexe todos los no primitivos, especialmente si espera muchos duplicados. ElijaWrappedArray
sobre estructuras anidadas siempre que sea posible. O incluso despliegue su propia serialización: USTED tendrá la mayor cantidad de información sobre cómo hacer una copia de seguridad eficiente de sus datos en bytes, ¡ USE !Dataset
para almacenar en caché su estructura, ya que utilizará una serialización más eficiente. Esto debería considerarse como un truco en comparación con el punto anterior. Construir su conocimiento de dominio en su algoritmo / serialización puede minimizar la memoria / espacio de caché en 100x o 1000x, mientras que todo lo que seDataset
obtendrá es 2x - 5x en memoria y 10x comprimido (parquet) en disco.http://spark.apache.org/docs/1.2.1/configuration.html
EDITAR: (para que pueda googlearme más fácilmente) Lo siguiente también es indicativo de este problema:
fuente
spark.executor.memory
porque definitivamente necesita cierta cantidad de memoria para la sobrecarga de E / S. Si lo usa todo, ralentizará su programa. La excepción a esto podría ser Unix, en cuyo caso tiene espacio de intercambio.Para agregar un caso de uso a esto que a menudo no se discute, presentaré una solución cuando envíe una
Spark
solicitudspark-submit
en modo local .De acuerdo con el gitbook Mastering Apache Spark de Jacek Laskowski :
Por lo tanto, si experimenta
OOM
errores con elheap
, es suficiente ajustar el endriver-memory
lugar delexecutor-memory
.Aquí hay un ejemplo:
fuente
Debe configurar la memoria offHeap como se muestra a continuación:
Entregue la memoria del controlador y la memoria del ejecutor según la disponibilidad de RAM de su máquina. Puede aumentar el tamaño de offHeap si aún enfrenta el problema OutofMemory .
fuente
config
resuelto el problema.Debe aumentar la memoria del controlador. Creo que en su carpeta $ SPARK_HOME / conf debería encontrar el archivo
spark-defaults.conf
, editarlo y configurarlo enspark.driver.memory 4000m
función de la memoria de su maestro. Esto es lo que solucionó el problema para mí y todo funciona sin problemasfuente
Eche un vistazo a los scripts de inicio; allí se establece un tamaño de almacenamiento dinámico Java, parece que no está configurando esto antes de ejecutar Spark Worker.
Puede encontrar la documentación para desplegar las escrituras aquí .
fuente
start up scripts
Desafortunadamente, el contenido del script vinculado a by ha cambiado. No existen tales opciones a partir del 2019-12-19Sufrí mucho de este problema, utilizamos la asignación dinámica de recursos y pensé que utilizaría los recursos de mi clúster para adaptarse mejor a la aplicación.
Pero la verdad es que la asignación dinámica de recursos no establece la memoria del controlador y la mantiene en su valor predeterminado, que es 1g.
Lo resolví estableciendo spark.driver.memory en un número que se adapte a la memoria de mi controlador (para 32 gb de ram lo configuré en 18 gb)
puede configurarlo usando el comando de envío de chispa de la siguiente manera:
Nota muy importante, esta propiedad no se tendrá en cuenta si la configura desde el código, de acuerdo con la documentación de spark:
fuente
En términos generales, la memoria chispe Executor JVM se puede dividir en dos partes. Memoria de chispa y memoria de usuario. Esto está controlado por la propiedad
spark.memory.fraction
: el valor está entre 0 y 1. Cuando trabaje con imágenes o realice un procesamiento intensivo de memoria en aplicaciones de chispa, considere disminuirspark.memory.fraction
. Esto hará que haya más memoria disponible para el trabajo de su aplicación. La chispa puede derramarse, por lo que seguirá funcionando con menos memoria compartida.La segunda parte del problema es la división del trabajo. Si es posible, particione sus datos en fragmentos más pequeños. Los datos más pequeños posiblemente necesitan menos memoria. Pero si eso no es posible, estás sacrificando el cómputo por la memoria. Por lo general, un solo ejecutor ejecutará múltiples núcleos. La memoria total de los ejecutores debe ser suficiente para manejar los requisitos de memoria de todas las tareas concurrentes. Si aumentar la memoria del ejecutor no es una opción, puede disminuir los núcleos por ejecutor para que cada tarea tenga más memoria para trabajar. Pruebe con 1 ejecutores de núcleo que tengan la mayor memoria posible que pueda brindar y luego siga aumentando los núcleos hasta encontrar el mejor conteo de núcleos.
fuente
¿Volcó su registro maestro de gc? Entonces encontré un problema similar y encontré que SPARK_DRIVER_MEMORY solo configuró el montón Xmx. El tamaño de almacenamiento dinámico inicial sigue siendo 1G y el tamaño de almacenamiento dinámico nunca escala hasta el almacenamiento dinámico Xmx.
Pasar "--conf" spark.driver.extraJavaOptions = -Xms20g "resuelve mi problema.
ps aux | grep java y verá el siguiente registro: =
24501 30.7 1.7 41782944 2318184 pts / 0 Sl + 18:49 0:33 / usr / java / latest / bin / java -cp / opt / spark / conf /: / opt / spark / jars / * -Xmx30g -Xms20g
fuente
La ubicación para establecer el tamaño del almacenamiento dinámico de memoria (al menos en spark-1.0.0) está en conf / spark-env. Las variables relevantes son
SPARK_EXECUTOR_MEMORY
&SPARK_DRIVER_MEMORY
. Más documentos están en la guía de implementaciónAdemás, no olvide copiar el archivo de configuración a todos los nodos esclavos.
fuente
SPARK_EXECUTOR_MEMORY
&SPARK_DRIVER_MEMORY
?SPARK_EXECUTOR_MEMORY
y qué error le indicaría que aumenteSPARK_DRIVER_MEMORY
?Tengo pocas sugerencias para el error mencionado anteriormente.
● Compruebe que la memoria del ejecutor asignada como ejecutor podría tener que lidiar con particiones que requieren más memoria de la asignada.
● Intente ver si hay más shuffles en vivo, ya que los shuffles son operaciones costosas, ya que involucran E / S de disco, serialización de datos y E / S de red.
● Usar uniones de difusión
● Evite usar groupByKeys e intente reemplazar con ReduceByKey
● Evite el uso de enormes objetos Java donde sea que se baraje
fuente
Según tengo entendido el código proporcionado anteriormente, carga el archivo y realiza la operación de mapeo y lo guarda de nuevo. No hay ninguna operación que requiera barajar. Además, no hay ninguna operación que requiera que los datos se lleven al controlador, por lo tanto, ajustar cualquier cosa relacionada con la reproducción aleatoria o el controlador puede no tener ningún impacto. El controlador tiene problemas cuando hay demasiadas tareas, pero esto fue solo hasta la versión 2.0.2 de spark. Puede haber dos cosas que van mal.
fuente
Establecer estas configuraciones exactas ayudó a resolver el problema.
fuente