Per chi lavora con un set di dati più grande e ancora disposto a trarre profitto dal parallelismo dello , rdd.coalesce(1).saveAsTextFile("path")
non è la soluzione. L'intera pipeline (dall'ultima azione spark alla memorizzazione) verrà eseguita su 1 executor.
È possibile invece primo eseguire il gasdotto su qualunque numero di esecutori e utilizzare saveAsTextFile
(che produrrà diversi file in output) e poi unire solo tutti questi file utilizzando apache FileSystem
api.
Il seguente metodo è data la RDD per memorizzare e il percorso dove memorizzarlo:
import org.apache.spark.rdd.RDD
import org.apache.hadoop.fs.{FileSystem, FileUtil, Path}
import org.apache.hadoop.conf.Configuration
def saveAsSingleTextFile(
outputRDD: RDD[String],
outputFile: String
): Unit = {
// Classic saveAsTextFile in a temporary folder:
outputRDD.saveAsTextFile(outputFile + ".tmp")
// The facility allowing file manipulations on hdfs:
val hdfs = FileSystem.get(new Configuration())
// Merge the folder into a single file:
FileUtil.copyMerge(
hdfs,
new Path(outputFile + ".tmp"),
hdfs,
new Path(outputFile),
true,
new Configuration(),
null)
// And we delete the intermediate folder:
hdfs.delete(new Path(outputFile + ".tmp"), true)
}
questo modo l'elaborazione è ancora distribuito e la parte fusione avviene in seguito, che limita la perdita di prestazioni.
In bonus è possibile fornire il nome esatto del file di output, contrariamente a rdd.coalesce (1) .saveAsTextFile ("mio/percorso") che produce il file my/percorso/parte-00000.
fonte
2018-02-09 18:37:45
È generalmente una cattiva prassi utilizzare un solo file in Big Data se il file è di grandi dimensioni. – samthebest
Qual è la procedura migliore se l'output fosse, ad esempio, un file ordinato? Mantienilo come una raccolta di file e fai in modo che i molti nomi di file di output siano una sorta di indice (ad esempio qualcosa come il primo file è denominato "aa", quelli centrali sono come "fg", l'ultimo "zzy")? – Rdesmond
Spesso accade che un intenso lavoro di scintilla genera solo un output molto piccolo (aggregazione, kpis, popolarità, ...) che viene prodotto su hdf, ma molto probabilmente usato da applicazioni non correlate ai big data. Più pulito e più facile in questo caso avere un singolo file con nome per trasferimenti e consumi. –