Ответ 1
Похоже, я нашел такое решение - используйте искру 2.0. Раньше я использовал 1.6.2 - это была последняя версия на момент выпуска. Я попытался использовать версию предварительного просмотра версии 2.0, но есть и проблема.
У меня есть файл csv с около 5000 строк и 950 столбцов. Сначала я загружаю его в DataFrame:
val data = sqlContext.read
.format(csvFormat)
.option("header", "true")
.option("inferSchema", "true")
.load(file)
.cache()
После этого я просматриваю все столбцы строк
val featuresToIndex = data.schema
.filter(_.dataType == StringType)
.map(field => field.name)
и хотите их индексировать. Для этого я создаю индексаторы для каждого столбца строки
val stringIndexers = featuresToIndex.map(colName =>
new StringIndexer()
.setInputCol(colName)
.setOutputCol(colName + "Indexed"))
и создать конвейер
val pipeline = new Pipeline().setStages(stringIndexers.toArray)
Но когда я пытаюсь преобразовать свой исходный dataframe с этим конвейером
val indexedDf = pipeline.fit(data).transform(data)
Я получаю 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)
...
Что я делаю неправильно? Спасибо.
Похоже, я нашел такое решение - используйте искру 2.0. Раньше я использовал 1.6.2 - это была последняя версия на момент выпуска. Я попытался использовать версию предварительного просмотра версии 2.0, но есть и проблема.
Скорее всего, недостаточно памяти для хранения всех кадров стека. Я испытываю нечто подобное при обучении RandomForestModel. Обходной путь, который работает для меня, заключается в том, чтобы запустить мое приложение-драйвер (этот веб-сервис) с дополнительными параметрами:
-XX:ThreadStackSize=81920 -Dspark.executor.extraJavaOptions='-XX:ThreadStackSize=81920'
Ожидается ошибка StackOverflowError. Нам нужно, чтобы код не создавал переполнение. Проверьте ниже вопрос и ответы, связанные с той же ошибкой.
fooobar.com/questions/358797/...
fooobar.com/questions/358800/...
Надеемся, что приведенные выше ссылки помогут вам.
StackOverflowError в Java Когда вызов функции вызывается Java-приложением, стек стека выделяется в стеке вызовов. Фрейм стека содержит параметры вызываемого метода, его локальные параметры и обратный адрес метода. Адрес возврата обозначает точку выполнения, из которой выполнение программы должно продолжаться после возврата вызванного метода. Если нет места для нового стека кадров, StackOverflowError вызывается виртуальной машиной Java (JVM). Наиболее распространенным случаем, который может исчерпать стек приложений Java, является рекурсия. В рекурсии метод запускается во время его выполнения. Рекурсия рассматривается как мощный метод программирования общего назначения, но его следует использовать с осторожностью, чтобы избежать исключения StackOverflowError.
Возможное решение 1. По умолчанию, Spark использует только сериализацию RDD. попробуйте с опцией persist on disk
2. Чтобы увеличить размер стека драйвера JVM, добавьте что-то вроде -Xss5m в параметры драйвера. Вполне вероятно, что некоторые рекурсии происходят, когда вы проверяете типы столбцов в data.schema
- драйвер-java-опции "-Xss 100M"
если возможно, поделиться файлом и полной трассировкой исключений.