私はSpark Jobをcsvファイルとして保存する効果的な方法を見つけようとしています。HadoopなどでSparkすべてのファイルはpart-00000
として保存されます。
spark指定したファイル名でファイルに保存する方法はありますか?
SparkはHadoop File System APIを使用してデータをファイルに書き込むため、これはやむを得ないことです。
rdd.saveAsTextFile("foo")
保存しようとしているRDD内のパーティションごとに1つのpart- *ファイルとともに「foo/part-XXXXX
」として保存されます。 RDDの各パーティションが個別のファイルに書き込まれる理由は、フォールトトレランスのためです。 3番目のパーティション(つまりpart-00002
)に書き込むタスクが失敗した場合、Spark=タスクを再実行し、部分的に書き込まれた/破損したpart-00002
を上書きします。他の部分:すべてが同じファイルに書き込んだ場合、単一のタスクを障害から回復するのははるかに困難です。
part-XXXXX
ファイルは、Spark/Hadoopベースのフレームワークですべて使用する場合、通常は問題ありません。なぜなら、それらはすべてHDFS APIを使用するため、読み取りを要求する場合「foo」、すべてfoo内のすべてのpart-XXXXX
ファイルも読み取ります。
この方法で行うことをお勧めします(Javaの例):
theRddToPrint.coalesce(1, true).saveAsTextFile(textFileName);
FileSystem fs = anyUtilClass.getHadoopFileSystem(rootFolder);
FileUtil.copyMerge(
fs, new Path(textFileName),
fs, new Path(textFileNameDestiny),
true, fs.getConf(), null);
Hadoop FileSystem opsに基づく another アプローチがあります。
アイデアはありますが、準備ができていないコードスニペットです。内部的に(名前のとおり)SparkはHadoop出力形式を使用します(HDFSから読み取る場合はInputFormat
と同様)。
HadoopのFileOutputFormat
には保護されたメンバーsetOutputFormat
があり、継承されたクラスから呼び出して他のベース名を設定できます。
Spark SQLを使用すると、1つのライナーでこれを実行できます
//implicits for magic functions like .toDf
import spark.implicits._
val df = Seq(
("first", 2.0),
("choose", 7.0),
("test", 1.5)
).toDF("name", "vals")
//write DataFrame/DataSet to external storage
df.write
.format("csv")
.save("csv/file/location")
それは本当にきれいな解決策ではありませんが、foreachRDD
()の中では基本的にあなたが好きなことをすることができ、新しいファイルを作成することもできます。
私のソリューションでは、これが私がすることです:出力をHDFSに保存し(フォールトトレランスの理由のため)、foreachRDD
内で、ローカルフォルダーに統計を含むTSVファイルも作成します。
それがあなたが必要とするものであるならば、おそらくあなたは同じことをすることができると思います。
http://spark.Apache.org/docs/0.9.1/streaming-programming-guide.html#output-operations