2016-08-01 4 views
0

Ich bin ziemlich neu in der funktionalen Programmierung und habe keine imperative Programmierung Hintergrund. Durch einige grundlegende Scala/Spark-Tutorials online gehen und einige Schwierigkeiten haben, eine Scala-Bewerbung durch Spark-Submission einzureichen.Problem Übergabe Anwendungsargument zu Spark-Submit mit Scala

Insbesondere bekomme ich eine java.lang.ArrayIndexOutOfBounds 0 Exception, die ich erforscht habe und festgestellt, dass das Array-Element an Position 0 der Schuldige ist. Wenn ich genauer hinsehe, sah ich, dass ein grundlegendes Debugging mir sagen könnte, ob die Main-Anwendung tatsächlich das Argument zur Laufzeit aufgriff - was nicht der Fall war. Hier ist der Code:

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) 
    } 
    } 
} 

Um den Antrag mit Funken einreichen Ich benutze:

spark-submit --class SparkMeApp --master "local[*]" --jars target\scala-2.10\firstsparkapplication_2.10-1.0.jar NetSetup.log 

... wo Netsetup.log im selben Verzeichnis wie, wo ich die Anwendung bin einreichen . Die Ausgabe der Anwendung ist einfach: 0. Wenn ich die try/catch zu entfernen, ist der Ausgang:

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) 

Es ist erwähnenswert, dass die Anwendung fein läuft, wenn ich das Argument und hart Code den Pfad zu dem Entfernen Logdatei. Ich weiß nicht wirklich, was ich hier vermisse. Jede Richtung würde geschätzt werden. Danke im Voraus!

+0

Fußnote: Ich habe versucht, den Dateinamen in einfache und doppelte Anführungszeichen in der Befehlszeile setzen, ohne Erfolg. – Jonathan

Antwort

0

Die Textdatei sollte in HDFS (bei Verwendung von HADOOP) oder in einem anderen von Ihnen zur Unterstützung von SPARK verwendeten DFS enthalten sein, um relative Pfade für die Anwendung zum Lesen der Daten zu übergeben. Sie sollten also die Datei in die DFS-Anwendung stellen, damit sie funktioniert. Andernfalls geben Sie nur den absoluten Pfad von Ihrem Betriebssystem-Dateisystem an.

Schauen Sie für Anweisungen zum Hinzufügen von Dateien zu HDFS und this verwandte Diskussion, die Ihnen helfen könnte.

Auch setzen Sie die Cluster durch die Anwendung zweimal verwendet werden: in dem Spark-conf (setMaster("local[*]")):

val conf = new SparkConf().setAppName("SparkMe Application").setMaster("local[*]") 

und in dem einreichen (--master "local[*]"):

spark-submit --class SparkMeApp --master "local[*]" --jars target\scala-2.10\firstsparkapplication_2.10-1.0.jar NetSetup.log 

Sie müssen Sie es nur einmal tun, wählen Sie eine von ihnen.

+1

Ich denke, das --jars-Flag erwartet mehrere .jar-Dateien oder Verzeichnisse, die durch Kommas getrennt sind, und danach erwartet das Spark-Submit-Skript das jar der Anwendung, das in diesem Fall NetSetup.log ist. Du solltest also die "--jars" Flagge entfernen. – Marco

+0

spark-submit arbeitet mit einem einzelnen jar, das an den Parameter --jars übergeben wird und die Argumente dafür unmittelbar danach erwartet. Also, die Spark-Submission ist in Ordnung, außer von den duplizierten Clustern Setup ive erwähnt. – andriosr

+1

--jars Flag wird verwendet, um zusätzliche Gläser hinzuzufügen, die zusammen mit dem App-Jar zum Cluster übertragen werden. Das Problem ist in diesem Fall, dass "target \ scala-2.10 \ firstsparkapplication_2.10-1.0.jar" als extra jar und "NetSetup.log" als application jar genommen wird. Kein Argument für die App – Marco

1

Sie tun Funken falsch übergeben. Der eigentliche Befehl ist

./spark-submit --class SparkMeApp --master "local[*]" \ 
example.jar examplefile.txt 

Sie müssen --jars nur passieren, wenn es externe Abhängigkeit und Sie wollen, dass Glas zu allen Testamentsvollstrecker verteilen.

Wenn Sie die log4j.properties in INFO/WARN aktiviert hätten, hätten Sie sie leicht erfassen können.

Warning: Local jar /home/user/Downloads/spark-1.4.0/bin/NetSetup.log does not exist, skipping. 
+0

Danke für den Tipp. Am Ende habe ich '--jars' aus dem Befehl entfernt und es hat sich gelohnt. – Jonathan

+0

Aus Neugier - wie ich noch neu bei all dem bin - wie würde man die log4j.properties zu info/warn? Ich sehe, dass es Pakete für log4j gibt, um dies programmatisch zu tun - obwohl es einen einfacheren Weg gibt? – Jonathan

0

- Problem gelöst-- Ich habe den Befehl "Funken senden" falsch verwendet. Durch das Entfernen von '--jars' aus dem Befehl wurde das Scala-Anwendungsargument durch die Funkenübermittlung aufgenommen.

Verwandte Themen