Spark-submit执行Uber-Jar任务无输出无错误日志问题求助
我来帮你排查这个头疼的问题——Spark Submit没输出、没日志,任务直接卡壳,这类情况通常和Uber-Jar构建、命令参数、日志配置或者依赖兼容性有关,咱们一步步来解决:
1. 先确认你打的是真正的Uber-Jar
sbt默认的sbt package命令只会打包你自己的代码,所有依赖(比如DL4J、ND4J这些)都没包含进去,这就会导致Spark找不到必要的类,任务悄无声息地失败。你需要用sbt-assembly插件来构建包含所有依赖的胖Jar:
- 第一步,在
project/plugins.sbt里添加插件(版本对应你的sbt版本,比如sbt 1.x用1.2.0没问题):addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "1.2.0") - 然后在
build.sbt里配置依赖合并策略,避免DL4J和Spark的重复文件冲突:assemblyMergeStrategy in assembly := { case PathList("META-INF", xs @ _*) => xs match { case ("MANIFEST.MF" | "INDEX.LIST" | "DEPENDENCIES") => MergeStrategy.discard case _ => MergeStrategy.first } case x => MergeStrategy.first } - 最后执行
sbt assembly,生成的Jar在target/scala-2.11/目录下,文件名一般是xxx-assembly-0.1.jar,这个才是能直接提交的Uber-Jar。
2. 修正Spark Submit的命令参数顺序
你把--packages参数放在了Jar路径后面,这是错误的!--packages是Spark Submit的全局参数,必须放在Jar文件名之前。而且如果已经用Uber-Jar打包了所有依赖,其实可以去掉--packages,避免重复依赖导致冲突。
正确的命令格式应该是这样:
spark-submit --class "lstm.SparkLSTM" \ --master local[*] \ # 如果用Uber-Jar就去掉下面这行,否则保留正确的依赖版本 --packages org.deeplearning4j:deeplearning4j-core:1.0.0-M2.1,org.nd4j:nd4j-native-platform:1.0.0-M2.1 \ your-assembly.jar
3. 强制输出日志,找到问题根源
任务没输出可能是日志级别太高,或者日志没打到控制台。你可以手动指定日志配置,强制输出详细日志:
- 先创建一个简单的
log4j.properties文件,放在能访问到的路径:log4j.rootLogger=INFO, console log4j.appender.console=org.apache.log4j.ConsoleAppender log4j.appender.console.target=System.out log4j.appender.console.layout=org.apache.log4j.PatternLayout log4j.appender.console.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n - 然后在Spark Submit命令里添加日志配置参数:
spark-submit --class "lstm.SparkLSTM" \ --master local[*] \ --conf "spark.driver.extraJavaOptions=-Dlog4j.configuration=file:/path/to/your/log4j.properties" \ --conf "spark.executor.extraJavaOptions=-Dlog4j.configuration=file:/path/to/your/log4j.properties" \ your-assembly.jar - 另外,也可以去Spark Standalone的日志目录找线索:worker节点的日志一般在
SPARK_HOME/work/app-<你的应用ID>/<worker ID>/下,看stdout和stderr文件,里面可能藏着没输出到控制台的错误信息。
4. 检查DL4J和Spark的依赖兼容性
DL4J和Spark的版本匹配很重要,比如你用的是Scala 2.11(从Jar名看stock_prediction_scala_2.11-0.1.jar),那DL4J得选支持Scala 2.11的版本,比如1.0.0-M2.1及以下——新版本的DL4J可能只支持Scala 2.12+,这会导致类找不到。
另外,ND4J的后端也要注意:如果用nd4j-native,要确保所有Spark节点都有对应的原生库;如果是跨平台环境,换成nd4j-cpu更稳妥。
5. 本地先跑通,排除远程环境问题
先别着急提交到远程服务器,在本地用Spark local模式跑一遍,比如直接用sbt run执行你的代码,或者用本地的Spark Submit运行Uber-Jar。如果本地也跑不起来,那问题大概率在代码或依赖上;如果本地能跑通,再排查远程服务器的Spark配置、权限或者网络问题。
内容的提问来源于stack exchange,提问作者rickyhai11

