tutorial spark software org examples java scala apache-spark apache-spark-mllib

java - org - spark software



Apache Spark: StackOverflowError al intentar indexar columnas de cadena (4)

Tengo archivo csv con aproximadamente 5000 filas y 950 columnas. Primero lo cargo a DataFrame:

val data = sqlContext.read .format(csvFormat) .option("header", "true") .option("inferSchema", "true") .load(file) .cache()

Después de eso busco todas las columnas de cadena

val featuresToIndex = data.schema .filter(_.dataType == StringType) .map(field => field.name)

y quieren indexarlos. Para eso creo indexadores para cada columna de cadena.

val stringIndexers = featuresToIndex.map(colName => new StringIndexer() .setInputCol(colName) .setOutputCol(colName + "Indexed"))

y crear tubería

val pipeline = new Pipeline().setStages(stringIndexers.toArray)

Pero cuando intento transformar mi marco de datos inicial con esta tubería

val indexedDf = pipeline.fit(data).transform(data)

Obtengo StackOverflowError

16/07/05 16:55:12 INFO DAGScheduler: Job 4 finished: countByValue at StringIndexer.scala:86, took 7.882774 s Exception in thread "main" java.lang.StackOverflowError at scala.collection.immutable.Set$Set1.contains(Set.scala:84) at scala.collection.immutable.Set$Set1.$plus(Set.scala:86) at scala.collection.immutable.Set$Set1.$plus(Set.scala:81) at scala.collection.mutable.SetBuilder.$plus$eq(SetBuilder.scala:22) at scala.collection.mutable.SetBuilder.$plus$eq(SetBuilder.scala:20) at scala.collection.generic.Growable$class.loop$1(Growable.scala:53) at scala.collection.generic.Growable$class.$plus$plus$eq(Growable.scala:57) at scala.collection.mutable.SetBuilder.$plus$plus$eq(SetBuilder.scala:20) at scala.collection.TraversableLike$class.to(TraversableLike.scala:590) at scala.collection.AbstractTraversable.to(Traversable.scala:104) at scala.collection.TraversableOnce$class.toSet(TraversableOnce.scala:304) at scala.collection.AbstractTraversable.toSet(Traversable.scala:104) at org.apache.spark.sql.catalyst.trees.TreeNode.containsChild$lzycompute(TreeNode.scala:86) at org.apache.spark.sql.catalyst.trees.TreeNode.containsChild(TreeNode.scala:86) at org.apache.spark.sql.catalyst.trees.TreeNode$$anonfun$4.apply(TreeNode.scala:280) at scala.collection.Iterator$$anon$11.next(Iterator.scala:409) ...

¿Qué estoy haciendo mal? Gracias.


El Error en Java Cuando una aplicación Java invoca una llamada de función, se asigna un marco de pila en la pila de llamadas. El marco de pila contiene los parámetros del método invocado, sus parámetros locales y la dirección de retorno del método. La dirección de retorno denota el punto de ejecución desde el cual, la ejecución del programa continuará después de que regrese el método invocado. Si no hay espacio para un nuevo marco de pila, entonces el Error es lanzado por la Máquina Virtual de Java (JVM). El caso más común que posiblemente puede agotar la pila de una aplicación Java es la recursión. En la recursión, un método se invoca a sí mismo durante su ejecución. La recursión se considera una poderosa técnica de programación de propósito general, pero se debe usar con precaución para evitar el error

La solución posible es 1. Por defecto, Spark usa solo la serialización RDD de memoria. prueba con una opción de persistir en el disco

2. para intentar aumentar el tamaño de la pila JVM del controlador, agregando algo como -Xss5m a las opciones del controlador. Es probable que ocurran recursiones cuando está verificando los tipos de columna en el archivo data.schema

--driver-java-options "-Xss 100M"

Si es posible, comparta el archivo y complete el rastreo de excepciones.


Lo más probable es que no haya suficiente memoria para mantener todos los marcos de pila. Experimento algo similar cuando entrené RandomForestModel. La solución que me funciona es ejecutar mi aplicación de controlador (que es el servicio web) con parámetros adicionales:

-XX:ThreadStackSize=81920 -Dspark.executor.extraJavaOptions=''-XX:ThreadStackSize=81920''


Parece que encontré el tipo de solución - usa spark 2.0. Anteriormente, usé 1.6.2: era la versión más reciente en el momento de la emisión. Intenté usar la versión preliminar de 2.0, pero también se reproduce el problema.