Spark 3.1.1创建SparkSession时栈溢出问题的触发原因与解决方法求助
SparkSession创建时栈溢出问题分析与解决
问题背景
在Spark 3.1.1环境下,通过spark-shell执行以下代码创建SparkSession时触发栈溢出错误:
val spark = org.apache.spark.sql.SparkSession.builder().appName("test") spark.getOrCreate()
核心错误栈:
java.lang.StackOverflowError at scala.reflect.io.ZipArchive$.splitPath(ZipArchive.scala:62) at scala.reflect.io.ZipArchive$.scala$reflect$io$ZipArchive$$dirName(ZipArchive.scala:58) at scala.reflect.io.ZipArchive.ensureDir(ZipArchive.scala:114) at scala.reflect.io.ZipArchive.ensureDir(ZipArchive.scala:114) ...(重复栈帧省略)
已确认问题关联scala-reflect-2.12.10.jar的路径处理,由SessionState初始化触发,需明确触发点与解决方案。
触发操作细节
Spark创建SparkSession的getOrCreate()流程中,以下步骤触发了问题:
- 当Session不存在时,Spark会初始化
SessionState,这一过程依赖Scala反射机制加载相关类(如SessionStateBuilder)。 - 反射过程中,
scala-reflect库的ZipArchive类需要解析scala-reflect-2.12.10.jar的路径。 - 由于路径存在异常(循环符号链接、冗余层级如重复
../等),ZipArchive.ensureDir()方法进入无限递归调用,最终导致栈溢出。
规避方案
1. 修复JAR路径异常
- 定位
scala-reflect-2.12.10.jar的存放目录,检查路径中是否存在循环符号链接、无效的路径层级,删除或修正这些异常项。 - 确保Spark类路径(如
SPARK_CLASSPATH)中该JAR的路径为绝对路径,无冗余的../或重复层级。
2. 升级scala-reflect版本
此问题是Scala 2.12.10版本scala-reflect的已知bug,2.12.11及以上版本已修复路径解析的递归问题:
- 替换Spark依赖中的
scala-reflect-2.12.10.jar为scala-reflect-2.12.11.jar(需保持Scala版本为2.12.x,与Spark 3.1.1兼容)。
3. 临时调整JVM栈大小(应急方案)
若需快速绕过问题,可通过增大JVM栈空间缓解栈溢出,但无法根治递归问题:
spark-shell --driver-java-options "-Xss4m"
内容的提问来源于stack exchange,提问作者the drugs don't work
相关产品推荐
相关产品推荐

