Spark java.lang.OutOfMemoryError: espacio del montón de Java

Resuelto Hellen asked hace 10 años • 0 respuestas

Mi cluster: 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 me 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?

Hellen avatar Jan 15 '14 20:01 Hellen
Aceptado

Tengo algunas sugerencias:

  • Si sus nodos están configurados para tener un máximo de 6 g para Spark (y están dejando un poco para otros procesos), utilice 6 g en lugar de 4 g spark.executor.memory=6g. Asegúrate de estar usando la mayor cantidad de memoria posible verificando la interfaz de usuario (dirá cuánta memoria estás usando)
  • Intente usar más particiones, debería tener de 2 a 4 por CPU. Aumentar el número de particiones con IME suele ser la forma más sencilla de hacer que un programa sea más estable (y, a menudo, más rápido). Para grandes cantidades de datos, es posible que necesites más de 4 por CPU. ¡He tenido que usar 8000 particiones en algunos casos!
  • Disminuya la fracción de memoria reservada para el almacenamiento en caché mediante spark.storage.memoryFraction. Si no usa cache()o persisten su código, esto también podría ser 0. El valor predeterminado es 0.6, lo que significa que solo obtiene 0.4 * 4 g de memoria para su montón. La reducción de IME en la fractura de memoria a menudo hace que los OOM desaparezcan. ACTUALIZACIÓN: A partir de Spark 1.6 aparentemente ya no necesitaremos jugar con estos valores, Spark los determinará automáticamente.
  • Similar al anterior pero con fracción de memoria aleatoria . Si su trabajo no necesita mucha memoria aleatoria, configúrelo en un valor más bajo (esto podría hacer que la reproducción aleatoria se derrame en el disco, lo que puede tener un impacto catastrófico en la velocidad). A veces, cuando se trata de una operación aleatoria que es OOM, necesitas hacer lo contrario, es decir, configurarla en algo grande, como 0.8, o asegurarte de permitir que tus operaciones aleatorias se derramen en el disco (es el valor predeterminado desde 1.0.0).
  • Tenga cuidado con las pérdidas de memoria , que a menudo se deben al cierre accidental de objetos que no necesita en sus lambdas. La forma de diagnosticar es buscar la "tarea serializada como XXX bytes" en los registros; si XXX es mayor que unos pocos k o más de un MB, es posible que tenga una pérdida de memoria. Ver https://stackoverflow.com/a/25270600/1586965
  • Relacionado con lo anterior; use variables de transmisión si realmente necesita objetos grandes.
  • Si está almacenando en caché RDD grandes y puede sacrificar algo de tiempo de acceso, considere serializar el RDD http://spark.apache.org/docs/latest/tuning.html#serialized-rdd-storage . O incluso almacenarlos en caché en el disco (lo que a veces no es tan malo si se usan SSD).
  • ( Avanzado ) En relación con lo anterior, evite Stringestructuras muy anidadas (como Mapclases de casos anidadas). Si es posible, intente utilizar únicamente tipos primitivos e indexar todos los no primitivos, especialmente si espera muchos duplicados. Elija WrappedArrayestructuras anidadas siempre que sea posible. O incluso implemente su propia serialización: USTED tendrá la mayor información sobre cómo realizar una copia de seguridad de sus datos en bytes de manera eficiente. ¡ ÚSALO !
  • ( un poco hacky ) Nuevamente, al almacenar en caché, considere usar a Datasetpara almacenar en caché su estructura, ya que utilizará una serialización más eficiente. Esto debe considerarse como un truco en comparación con el punto anterior. Incorporar el conocimiento de su dominio en su algoritmo/serialización puede minimizar la memoria/espacio de caché en 100x o 1000x, mientras que todo lo que Datasetprobablemente dará es 2x - 5x en memoria y 10x comprimido (parquet) en disco.

http://spark.apache.org/docs/1.2.1/configuration.html

EDITAR : (Para poder buscar en Google más fácilmente) Lo siguiente también es indicativo de este problema:

java.lang.OutOfMemoryError : GC overhead limit exceeded
samthebest avatar Mar 30 '2014 10:03 samthebest

Para agregar un caso de uso a esto que a menudo no se analiza, propondré una solución al enviar una Sparksolicitud spark-submiten modo local .

Según el gitbook Mastering Apache Spark de Jacek Laskowski :

Puede ejecutar Spark en modo local. En este modo de implementación de JVM única no distribuida, Spark genera todos los componentes de ejecución (controlador, ejecutor, backend y maestro) en la misma JVM. Este es el único modo en el que se utiliza un controlador para la ejecución.

Por lo tanto, si experimenta OOMerrores con heap, basta con ajustar el driver-memoryen lugar del executor-memory.

Here is an example:

spark-1.6.1/bin/spark-submit
  --class "MyClass"
  --driver-memory 12g
  --master local[*] 
  target/scala-2.10/simple-project_2.10-1.0.jar 
Brian avatar Mar 12 '2016 18:03 Brian