Spark 训练机器学习模型莫名报错(java.lang.stackoverflow)
遇到一个问题,为此熬了夜,如果没遇到这篇文章,很难发现原因。
具体描述一下问题,我的代码如下:
var dataDf = ... // load from other place
val inDoubleCols = dataDf.dtypes.filter(_._2 != "DoubleType"
).map(_._1).toArray[String]
inDoubleCols.forearch(column => {dataDf = dataDf.withColumn(column, col(column).cast(DoubleType))
})val classifier: LightGBMClassifier = new LightGBMClassifier().setFeaturesCol("features").setLabelCol("label")
val model = classifier.fit(dataDf)
在 fit 那句报错了,如下:
...
21/09/17 11:37:34 INFO SparkContext: Created broadcast 7 from rdd at LightGBMBase.scala:195
21/09/17 11:37:34 INFO FileSourceScanExec: Planning scan with bin packing, max size: 134217728 bytes, open cost is considered as scanning 4194304 bytes.
Exception in thread "main" java.lang.StackOverflowErrorat org.apache.spark.sql.catalyst.trees.TreeNode.$anonfun$foreachUp$1$adapted(TreeNode.scala:126)at scala.collection.immutable.List.foreach(List.scala:431)at org.apache.spark.sql.catalyst.trees.TreeNode.foreachUp(TreeNode.scala:126)at org.apache.spark.sql.catalyst.trees.TreeNode.$anonfun$foreachUp$1(TreeNode.scala:126)at org.apache.spark.sql.catalyst.trees.TreeNode.$anonfun$foreachUp$1$adapted(TreeNode.scala:126)at scala.collection.immutable.List.foreach(List.scala:431)at org.apache.spark.sql.catalyst.trees.TreeNode.foreachUp(TreeNode.scala:126)at org.apache.spark.sql.catalyst.trees.TreeNode.$anonfun$foreachUp$1(TreeNode.scala:126)at org.apache.spark.sql.catalyst.trees.TreeNode.$anonfun$foreachUp$1$adapted(TreeNode.scala:126)at scala.collection.immutable.List.foreach(List.scala:431)at org.apache.spark.sql.catalyst.trees.TreeNode.foreachUp(TreeNode.scala:126)at org.apache.spark.sql.catalyst.trees.TreeNode.$anonfun$foreachUp$1(TreeNode.scala:126)at org.apache.spark.sql.catalyst.trees.TreeNode.$anonfun$foreachUp$1$adapted(TreeNode.scala:126)at scala.collection.immutable.List.foreach(List.scala:431)at org.apache.spark.sql.catalyst.trees.TreeNode.foreachUp(TreeNode.scala:126)at org.apache.spark.sql.catalyst.trees.TreeNode.$anonfun$foreachUp$1(TreeNode.scala:126)at org.apache.spark.sql.catalyst.trees.TreeNode.$anonfun$foreachUp$1$adapted(TreeNode.scala:126)at scala.collection.immutable.List.foreach(List.scala:431)at org.apache.spark.sql.catalyst.trees.TreeNode.foreachUp(TreeNode.scala:126)...
很长很长,实际上就是函数把 stack (栈)给堆满了。我和另外两个前辈没见过这种情况,管这种情况叫“超级树”。
按照一般的思路,在 fit 这行报错,那我们怀疑就是 fit 内部某些机制错了,于是各种更换 scala 版本、 spark 版本、 mmlspark 版本、增加 Xms 等等配置…一直到深夜都没解决“超级树”问题。
当时并不了解 spark 运行机制。那么,问题到底出在哪里呢?
换个思路,其实但凡懂一点计算机原理、思维别太死板也能看出来, 上面的 java.lang.stackoverflow 是因为积攒了太多函数没运行。
为什么到了 fit 这里会积攒太多函数呢?因为 Spark 里面有“懒操作”一说:比如在 数据 dataDf 的 withColumn 这个函数被调用时,不一定要立即去做这件事,而是积攒着,直到 dataDf 需要被缓存、被展示、被计算得到新的值时,之前积攒的一些列操作才开始被调用。 你看我前面 foreach 了那么多 withColumn ,那自然,积攒的函数就很多,就会在 fit 时 java.lang.stackoverflow 。
我当时的解决方案是加入一个 cache()
:
var dataDf = ... // load from other place
val inDoubleCols = dataDf.dtypes.filter(_._2 != "DoubleType"
).map(_._1).toArray[String]
inDoubleCols.forearch(column => {dataDf = dataDf.withColumn(column, col(column).cast(DoubleType))
})dataDf.cache() // 把之前积攒的懒操作做一做val classifier: LightGBMClassifier = new LightGBMClassifier().setFeaturesCol("features").setLabelCol("label")
val model = classifier.fit(dataDf)
现在看来,上面的代码还是太糟糕了。
既然都用函数式编程了,就不要有 cols.forearch(c => { x = x... })
这么愚蠢的写法。而且对每一列进行 withColumn 来转换类型是极其极其低效率的。
如果给我改,该怎么改?
var dataDf = ... // load from other place
val doubleCols = dataDf.columns.map(f => col(f).cast(DoubleType)
)dataDf.select(doubleCols: _*)
dataDf.show(1, true) // 把之前积攒的懒操作做一做val classifier: LightGBMClassifier = new LightGBMClassifier().setFeaturesCol("features").setLabelCol("label")
val model = classifier.fit(dataDf)
注意这里有两个经验,新手必须要越早知道越好:
- select 进行批量类型转换,效率远高于 withColumn
- cache 可以用,但是不能乱用;在不需要把数据传入缓存、只想清空懒操作的情况下, show 没准是更高效的选择
归根结底是当时不了解 Spark 原理。可能小厂就是这样,人手不够,需求还贼多,我连 scala 都没听说过,就接手这么庞大个 Spark 项目,也没有时间学习原理、公司里也没人会没人带我…赶鸭子上架了属于是。现在空下来了,先把原理补一补。
Spark 训练机器学习模型莫名报错(java.lang.stackoverflow)相关推荐
- java 报错 定位,问题定位分享(2)spark任务一定几率报错java.lang.NoSuchFieldError: HIVE_MOVE_FILES_THREAD_COUNT...
用yarn cluster方式提交spark任务时,有时会报错,报错几率是40%,报错如下: 18/03/15 21:50:36 116 ERROR ApplicationMaster91: User ...
- Spark读取文件,报错java.lang.ArrayIndexOutOfBoundsException
背景: 在 Spark 解析文件的时候,忽然报错 java.lang.ArrayIndexOutOfBoundsException.排查问题,也没发现有任何的异常.最后发现文件中,有一行数据的最后一个 ...
- DRP问题集结(一)-Tomcat无法启动,报错java.lang.NoClassDefFoundError: org/apache/juli/logging/LogFactory...
问题一: Tomcat无法启动,报错java.lang.NoClassDefFoundError: org/apache/juli/logging/LogFactory 问题二:[Error]Jav ...
- WildFly 报错 java.lang.NoClassDefFoundError
在eclipse上WildFly部署项目后,启动一直报错java.lang.NoClassDefFoundError,功夫不负有心人,终于解决. 解决方案 查了网上很多资料,有说环境变量配置不对的,有 ...
- 首次使用eclipes运行项目报错“Java.lang.ClassNotFoundException”
首次使用eclipes运行项目报错"Java.lang.ClassNotFoundException" 运行项目时提示: 解决方法: 1.点击菜单-Project-Build Au ...
- 解决Tomcat下IntelliJ IDEA报错java.lang.NoClassDefFoundError: javax/servlet/ServletContextListener
解决Tomcat下IntelliJ IDEA报错java.lang.NoClassDefFoundError: javax/servlet/ServletContextListener 笔者在做代 ...
- Spring Boot单元测试报错java.lang.IllegalStateException: Could not load TestContextBootstrapper [null]
一:运行test类方法时候报错 报错 java.lang.IllegalStateException: Could not load TestContextBootstrapper [null]. S ...
- Hive报错java.lang.NoClassDefFoundError: org/codehaus/jackson/JsonFactory
一 问题 Hive报错java.lang.NoClassDefFoundError:org/codehaus/jackson/JsonFactory 二 原因 Hadoop版本是0.20.2.$HAD ...
- SpringBoot+MyBatis启动报错java.lang.NoClassDefFoundError: org/w3c/dom/ElementTraversal
2019独角兽企业重金招聘Python工程师标准>>> 如题,在启动SpringBoot时报SpringBoot+MyBatis启动报错java.lang.NoClassDefFou ...
最新文章
- linux gstack pstack 进程运行堆栈查看工具
- 使用c++进行Windows编程中各种操作文件的方法 【转】
- 从运维的角度理解Iaas、Paas、Saas云计算
- MySQL 5.6 my.cnf 参数说明(转)
- table表格的增删查改、图片的处理、数据的导入导出
- 制作个性化gurb菜单背景图片
- php ini文件操作类,操作.ini文件的好PHP类
- NLP学习03--递归神经网络RNN
- Dart教程(一):dart安装
- hive编程指南电子版_2020浙江省太阳能利用及节能技术重点实验室开放基金课题申请指南...
- python 获得时间戳_Python 获取时间戳
- d3 企业图谱 仿天眼查 企查查
- 心理测试详解:猴子小鸟蛇包
- 大学四年,我做过哪些兼职
- *p++、*(p++)、(*p)++、*++p、++*p的区别
- 给 FreeBSD 12.1 安装 GNOME3 图形界面
- 损失函数focal loss深度理解与简单实现
- ChatGPT的各项超能力从哪儿来?万字拆解追溯技术路线图来了!
- 只看活动结案报告?营销活动效果你还能做的更好
- android怎么链接汽车,3如何将Android与汽车音频连接起来
热门文章
- 函数专题:sum、row_number、count、rank\dense_rank over
- 【Oracle】ORA-06510: PL/SQL: 用户定义的异常错误未得到处理
- Mysql解决死锁的问题,防止阻塞
- Java异常与异常处理简单使用
- 【火炉炼AI】深度学习008-Keras解决多分类问题
- DB2添加数据时主键、唯一键冲突的解决方法
- 解决IE浏览器URL乱码的问题
- VS 2005部署应用程序提示“应用程序无法正常启动( 0x0150002)” 解决方案
- 解决Ajax异步请求中传数组参数,后台无法接收问题
- eureka依赖导入失败以及eureka中没有@EnableEurekaServer异常