1

Ich verwende den folgenden Scala-Code, um eine Textdatei in S3 mit Apache Spark in AWS EMR zu erstellen.Schreiben Sie eine Datei in S3 mit Spark on EMR

def createS3OutputFile() { 
    val conf = new SparkConf().setAppName("Spark Pi") 
    val spark = new SparkContext(conf) 
    // use s3n ! 
    val outputFileUri = s"s3n://$s3Bucket/emr-output/test-3.txt" 
    val arr = Array("hello", "World", "!") 
    val rdd = spark.parallelize(arr) 
    rdd.saveAsTextFile(outputFileUri) 
    spark.stop() 
    } 

def main(args: Array[String]): Unit = { 
    createS3OutputFile() 
    } 

Ich erstelle ein fettes JAR und lade es auf S3 hoch. Ich habe dann SSH in den Cluster-Master und führen Sie den Code mit:

spark-submit \ 
    --deploy-mode cluster \ 
    --class "$class_name" \ 
    "s3://$s3_bucket/$app_s3_key" 

Ich sehe dies in der S3-Konsole: anstelle von Dateien Ordner vorhanden sind.

enter image description here

Jeder Ordner (zum Beispiel Test-3.txt) enthält eine lange Liste von Blockdateien. Bild unten:

enter image description here

Wie kann ich Ausgang eine einfache Textdatei S3 als die Ausgabe meines Funkenjobs?

Antwort

4

Versuch dies zu tun:

rdd.coalesce(1, shuffle = true).saveAsTextFile(...)

Mein Verständnis ist, dass das shuffle = true Argument dies parallel auftreten verursachen, so wird es Ausgabe eine einzelne Textdatei, aber nicht mit massiven Datendateien vorsichtig sein.

Here sind einige weitere Details zu diesem Problem zur Hand.

+0

Ich bin neu in Scala und Spark. Was ist der "kanonische" Weg, um Ergebnisse von einem Spark-Job zu erhalten? Schreibst du so wie ich in eine Datei? Erstellt es eine Datei mit nativen Java-Funktionen? – BlackSheep

+0

@BlackSheep Kommt wirklich auf die Aufgabe an, gibt es wirklich keinen offiziellen Weg. Wie beim Erstellen der Datei wird jede RDD-Partition die Aufgabe ausführen, die Sie ihr aufgetragen haben. In diesem Fall erstellt jede RDD-Partition eine Datei und schreibt in ihre eigene Datei. – TheM00s3

+0

Dies erzeugt immer noch die Ordnerstruktur, aber mit nur einem Kind 'part-00000'. – Tim

-1

Spark ist verteiltes Rechnen. Das bedeutet, dass Ihr Code auf mehreren Knoten ausgeführt wird.

saveAsTextFile() Methode akzeptiert file path, nicht der Dateiname.

Sie könnten coalesce() oder repartition verwenden, um die Anzahl der Teiledateien zu verringern. Aber es wird immer noch unter dem Dateipfad erstellt.

Alternativ können Sie den Dateinamen ändern oder mehrere Bauteildateien in eine Bauteildatei zusammenführen, indem Sie die FileUtil Klasse von Hadoop File System verwenden.

Shop RDD

rdd.saveAsTextFile("s3n://bucket/path/") 

auch bis S3, überprüfen this

+0

Können Sie ein Beispiel angeben, in dem die Ausgabe des Jobs in S3 als Datei gespeichert wird? Sie können die einfachste Ausgabe auswählen - eine Anzahl (#). Wie speichere ich das als Ausgabe in EMR? – BlackSheep

+0

@BlackSheep: Meine Antwort aktualisiert, um RDD zu s3 zu speichern. – Shankar

+1

'saveAsTextFile' ist buchstäblich das, was ich getan habe, wie in der Frage angegeben. Wie löst das mein Problem? – BlackSheep

Verwandte Themen