我对函数式编程很陌生,并且没有必要的编程背景。在线运行一些基本的scala / spark教程,并且在通过spark-submit提交Scala应用程序时遇到一些困难。
特别是我得到了一个java.lang.ArrayIndexOutOfBounds 0 Exception,我已经研究过并发现位置0的数组元素是罪魁祸首。进一步研究,我看到一些基本的调试可以告诉我主应用程序是否真的在运行时获取参数 - 事实并非如此。这是代码:
import org.apache.spark.{SparkConf, SparkContext}
object SparkMeApp {
def main(args: Array[String]) {
try {
//program works fine if path to file is hardcoded
//val logfile = "C:\\Users\\garveyj\\Desktop\\NetSetup.log"
val logfile = args(0)
val conf = new SparkConf().setAppName("SparkMe Application").setMaster("local[*]")
val sc = new SparkContext(conf)
val logdata = sc.textFile(logfile, 2).cache()
val numFound = logdata.filter(line => line.contains("found")).count()
val numData = logdata.filter(line => line.contains("data")).count()
println("")
println("Lines with found: %s, Lines with data: %s".format(numFound, numData))
println("")
}
catch {
case aoub: ArrayIndexOutOfBoundsException => println(args.length)
}
}
}
使用spark-submit提交申请我使用:
spark-submit --class SparkMeApp --master "local[*]" --jars target\scala-2.10\firstsparkapplication_2.10-1.0.jar NetSetup.log
...其中NetSetup.log与我提交应用程序的目录位于同一目录中。应用程序的输出只是:0。如果我删除了try / catch,则输出为:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0
at SparkMeApp$.main(SparkMeApp.scala:12)
at SparkMeApp.main(SparkMeApp.scala)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.apache.spark.deploy.SparkSubmit$.org$apache$spark$deploy$SparkSubmit$$runMain(SparkSubmit.scala:731)
at org.apache.spark.deploy.SparkSubmit$.doRunMain$1(SparkSubmit.scala:181)
at org.apache.spark.deploy.SparkSubmit$.submit(SparkSubmit.scala:206)
at org.apache.spark.deploy.SparkSubmit$.main(SparkSubmit.scala:121)
at org.apache.spark.deploy.SparkSubmit.main(SparkSubmit.scala)
值得指出的是,如果我删除参数并硬编码日志文件的路径,应用程序运行正常。真的不知道我在这里缺少什么。任何方向将不胜感激。提前谢谢!
答案 0 :(得分:1)
你做错了火花提交。实际命令是
./spark-submit --class SparkMeApp --master "local[*]" \
example.jar examplefile.txt
只有在存在外部依赖关系并且您希望将该jar分发给所有执行程序时,才需要传递--jars。
如果您已将log4j.properties启用为INFO / WARN,则可以轻松捕获它。
Warning: Local jar /home/user/Downloads/spark-1.4.0/bin/NetSetup.log does not exist, skipping.
答案 1 :(得分:0)
文本文件应该是HDFS(如果使用HADOOP)或您用来支持SPARK的任何其他DFS,以便传递应用程序读取数据的相对路径。因此,您应该将文件放入DFS以使您的应用程序正常工作,否则只提供OS文件系统的绝对路径。
查看here有关如何向HDFS添加文件的说明,以及可能对您有帮助的this相关讨论。
此外,您要将应用程序使用的集群设置两次:在Spark conf(setMaster("local[*]")
)中:
val conf = new SparkConf().setAppName("SparkMe Application").setMaster("local[*]")
并在提交(--master "local[*]"
)中:
spark-submit --class SparkMeApp --master "local[*]" --jars target\scala-2.10\firstsparkapplication_2.10-1.0.jar NetSetup.log
你只需要做一次,选择其中一个。
答案 2 :(得分:0)
- 问题解决了 - 我错误地使用了spark-submit命令。通过从命令中删除“--jars”,scala应用程序参数被spark-submit选中。