Apache Spark:尝试索引字符串列时出现 StackOverflowError
Apache Spark: StackOverflowError when trying to indexing string columns
我有大约 5000 行和 950 列的 csv 文件。首先我将它加载到 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)
但是当我尝试使用此管道转换我的初始数据帧时
val indexedDf = pipeline.fit(data).transform(data)
我收到 WhosebugError
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.WhosebugError
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(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.apply(TreeNode.scala:280)
at scala.collection.Iterator$$anon.next(Iterator.scala:409)
...
我做错了什么?
谢谢。
Java 中的 WhosebugError
当 Java 应用程序调用函数调用时,会在调用堆栈上分配一个堆栈帧。堆栈帧包含被调用方法的参数、它的局部参数和方法的return地址。 return 地址表示执行点,在调用的方法 returns 之后程序将继续执行。如果没有 space 新堆栈帧,则 Java 虚拟机 (JVM) 会抛出 WhosebugError。
可能耗尽 Java 应用程序堆栈的最常见情况是递归。在递归中,方法在执行期间调用自身。递归被认为是一种强大的通用编程技术,但必须谨慎使用,以避免 WhosebugError。
可能的解决方法是
1.By 默认情况下,Spark 仅使用内存 RDD 序列化。尝试使用磁盘持久化选项
2.to 尝试增加驱动程序的 JVM 堆栈大小,在驱动程序选项中添加类似 -Xss5m 的内容。当您检查 data.schema
中的列类型时,可能会发生一些递归
--驱动-java-选项“-Xss 100M”
如果可能,共享文件并完成异常跟踪。
很可能只是没有足够的内存来保存所有堆栈帧。我在训练 RandomForestModel 时遇到了类似的事情。对我有用的解决方法是 运行 我的驱动程序应用程序(即 Web 服务)带有附加参数:
-XX:ThreadStackSize=81920 -Dspark.executor.extraJavaOptions='-XX:ThreadStackSize=81920'
似乎我找到了解决方案——使用 spark 2.0。以前,我使用 1.6.2 - 它是发布时的最新版本。我试过用2.0预览版,也有问题重现
我有大约 5000 行和 950 列的 csv 文件。首先我将它加载到 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)
但是当我尝试使用此管道转换我的初始数据帧时
val indexedDf = pipeline.fit(data).transform(data)
我收到 WhosebugError
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.WhosebugError
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(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.apply(TreeNode.scala:280)
at scala.collection.Iterator$$anon.next(Iterator.scala:409)
...
我做错了什么? 谢谢。
Java 中的 WhosebugError 当 Java 应用程序调用函数调用时,会在调用堆栈上分配一个堆栈帧。堆栈帧包含被调用方法的参数、它的局部参数和方法的return地址。 return 地址表示执行点,在调用的方法 returns 之后程序将继续执行。如果没有 space 新堆栈帧,则 Java 虚拟机 (JVM) 会抛出 WhosebugError。 可能耗尽 Java 应用程序堆栈的最常见情况是递归。在递归中,方法在执行期间调用自身。递归被认为是一种强大的通用编程技术,但必须谨慎使用,以避免 WhosebugError。
可能的解决方法是 1.By 默认情况下,Spark 仅使用内存 RDD 序列化。尝试使用磁盘持久化选项
2.to 尝试增加驱动程序的 JVM 堆栈大小,在驱动程序选项中添加类似 -Xss5m 的内容。当您检查 data.schema
中的列类型时,可能会发生一些递归--驱动-java-选项“-Xss 100M”
如果可能,共享文件并完成异常跟踪。
很可能只是没有足够的内存来保存所有堆栈帧。我在训练 RandomForestModel 时遇到了类似的事情。对我有用的解决方法是 运行 我的驱动程序应用程序(即 Web 服务)带有附加参数:
-XX:ThreadStackSize=81920 -Dspark.executor.extraJavaOptions='-XX:ThreadStackSize=81920'
似乎我找到了解决方案——使用 spark 2.0。以前,我使用 1.6.2 - 它是发布时的最新版本。我试过用2.0预览版,也有问题重现