2017-07-17 7 views
1

Ich bin neu zu funken. Ich habe einige json Daten, die als HttpResponse kommt. Ich muss diese Daten in Hive-Tabellen speichern. Jede Anforderung HttpGet gibt einen JSON zurück, der eine einzelne Zeile in der Tabelle darstellt. Aus diesem Grund muss ich einzelne Zeilen als Dateien im Verzeichnis der Hive-Tabelle schreiben.Rekursives Hinzufügen von Zeilen zu einem Datenrahmen

Aber ich fühle mich zu viele kleine Dateien wird die Geschwindigkeit und Effizienz zu reduzieren. Also gibt es eine Möglichkeit, dass ich rekursiv neue Zeilen zum Dataframe hinzufügen und es auf einmal in das Hive-Tabellenverzeichnis schreiben kann. Ich denke, das wird auch die Laufzeit meines Spark-Codes reduzieren.

Beispiel:

for(i <- 1 to 10){ 
newDF = hiveContext.read.json("path") 
df = df.union(newDF) 
} 
df.write() 

Ich verstehe, dass der Datenrahmen unveränderlich ist. Gibt es einen Weg, dies zu erreichen?

Jede Hilfe wäre willkommen. Vielen Dank.

Antwort

1

Sie meist auf dem richtigen Weg sind, was Sie wollen, ist, mehrere einzelne Datensätze als Seq[DataFrame], und dann reduzieren Sie die Seq[DataFrame] zu einem einzigen DataFrame von unioning sie zu erhalten.

aus dem Code Gehen Sie zur Verfügung gestellt:

val BatchSize = 100 
val HiveTableName = "table" 

(0 until BatchSize). 
map(_ => hiveContext.read.json("path")). 
reduce(_ union _). 
write.insertInto(HiveTableName) 

Alternativ, wenn Sie die HTTP-Anfragen durchführen möchten, wie Sie gehen, können wir das auch tun. Nehmen wir an, Sie haben eine Funktion, die die HTTP-Anforderung hat und wandelt es in ein Datenrahmen:

def obtainRecord(...): DataFrame = ??? 

Sie können entlang der Linien von etwas tun:

val HiveTableName = "table" 
val OtherHiveTableName = "other_table" 
val jsonArray = ??? 

val batched: DataFrame = 
    jsonArray. 
    map { parameter => 
     obtainRecord(parameter) 
    }. 
    reduce(_ union _) 
batched.write.insertInto(HiveTableName) 
batched.select($"...").write.insertInto(OtherHiveTableName) 
+0

Danke für diese Antwort. Ich versuche das zu implementieren.Um meine get-Anfrage zu posten, benötige ich einen Parameter von jedem Element eines json-Arrays (das früher abgerufen wurde). Also, gibt es eine bessere Möglichkeit, die for-Schleife zu implementieren, so dass ich eine Variable haben kann, die mit jeder Iteration zunimmt (diese Variable wird verwendet, um auf den Parameter in jedem Element des Arrays zuzugreifen)? –

+0

Brauchen Sie nur einen Index, der von 0 bis zu was? –

+0

Ich habe gerade die Antwort aktualisiert, ich denke, besser widerspiegeln, was Sie versuchen zu tun. Dies setzt voraus, dass Sie das abgerufene JSON-Array auf einmal bearbeiten (und in eine einzelne Datei schreiben) möchten. Sie können auch das JSON-Array zuerst aufteilen oder alternativ mehrere JSON-Arrays verketten, je nachdem, was Sie tun möchten. –

0

Sie verwenden Spark eindeutig falsch. Apache Spark ist ein analytisches System, keine Datenbank-API. Es bietet keinen Vorteil, Spark zu verwenden, um die Hive-Datenbank so zu ändern. Dies kann nur zu einer erheblichen Leistungseinbuße führen, ohne von den Spark-Funktionen einschließlich der verteilten Verarbeitung zu profitieren.

Stattdessen sollten Sie den Hive-Client direkt für Transaktionsvorgänge verwenden.

+0

Es tut mir leid, aber verstanden Sie meine Frage ? Ich suche, um den Datenrahmen zu speichern, den ich von einem Json zum Stocktabellenverzeichnis erhielt. Ich versuche nicht, Hive-Tabellen/Datenbanken mit Spark zu modifizieren. –

+0

Dies ist keine Antwort auf die Frage; Es sollte stattdessen ein Kommentar zu der Frage sein. – TriskalJM

0

Wenn Sie alle Daten im Batch-Download (zum Beispiel mit einem Skript mit curl oder einem anderen Programm) und speichern Sie sie in einer Datei (oder viele Dateien, Spark kann ein ganzes Verzeichnis auf einmal laden) können Sie Laden Sie dann diese Datei (oder Dateien) auf einmal in Spark, um Ihre Verarbeitung zu tun. Ich würde auch sehen, dass es die Webapi als Endpunkte, um alle Daten, die Sie benötigen, anstatt nur einen Datensatz auf einmal zu holen.

+0

Danke für die Antwort. Was Sie geben, ist ein guter Ansatz. Aber ich kann nicht alle Daten gleichzeitig aus der API holen. Und ich muss den Datenrahmen als JSON-Datei speichern. Ist es möglich, eine json-Datei mit allen Datensätzen zu erstellen (mit Java)? Wenn ja, kann ich diese Datei einfach in meinen Datenrahmen einlesen. –

+0

@HemanthAnnavarapu ja das ist, was ich vorschlug, laden Sie einfach alle Daten in eine Datei oder mehrere Dateien vor der Zeit. Etwas wie "curl -w" \ n "[url] >> [jsonfile]' in einer Schleife über alle URLs sollte funktionieren. Sie können den Download auch mit Java oder Scala oder einer anderen Sprache, die Sie mögen, machen. – puhlen

Verwandte Themen