web-dev-qa-db-ja.com

スパークでsaveAsTextFileのときにファイルに名前を付ける方法は?

sparkバージョン1.5.1でテキストファイルとして保存する場合、使用するのはrdd.saveAsTextFile('<drectory>')です。

しかし、そのディレクトリでファイルを検索したい場合、どのように名前を付ければよいですか?

現在、part-00000、これはデフォルトである必要があります。名前を付けるにはどうすればよいですか?

8
Hunle

上記のコメントで述べたように、例を含むドキュメントは here にあります。そして、メソッドの説明saveAsTextFileを引用します:

要素の文字列表現を使用して、このRDDをテキストファイルとして保存します。

次の例では、単純なRDDをファイルに保存してから、それをロードしてその内容を印刷します。

samples = sc.parallelize([
    ("[email protected]", "Alberto", "Bonsanto"),
    ("[email protected]", "Miguel", "Bonsanto"),
    ("[email protected]", "Stranger", "Weirdo"),
    ("[email protected]", "Dakota", "Bonsanto")
])

print samples.collect()

samples.saveAsTextFile("folder/here.txt")
read_rdd = sc.textFile("folder/here.txt")

read_rdd.collect()

出力は

('[email protected]', 'Alberto', 'Bonsanto')
('[email protected]', 'Miguel', 'Bonsanto')
('[email protected]', 'Stranger', 'Weirdo')
('[email protected]', 'Dakota', 'Bonsanto')

[u"('[email protected]', 'Alberto', 'Bonsanto')",
 u"('[email protected]', 'Miguel', 'Bonsanto')",
 u"('[email protected]', 'Stranger', 'Weirdo')",
 u"('[email protected]', 'Dakota', 'Bonsanto')"]

Unixベースの端末を使用して見てみましょう。

usr@Host:~/folder/here.txt$ cat *
('[email protected]', 'Alberto', 'Bonsanto')
('[email protected]', 'Miguel', 'Bonsanto')
('[email protected]', 'Stranger', 'Weirdo')
('[email protected]', 'Dakota', 'Bonsanto')
7

この質問に対する正しい答えは、saveAsTextFileでは実際のファイルに名前を付けることができないということです。

これは、データがパーティション化されており、saveAsTextFile(...)への呼び出しのパラメーターとして指定されたパス内で、それをディレクトリとして扱い、パーティションごとに1つのファイルを書き込むためです。

rdd.coalesce(1).saveAsTextFile('/some/path/somewhere')を呼び出すと、_/some/path/somewhere/part-0000.txt_が作成されます。

これ以上の制御が必要な場合は、rdd.collect()を実行した後に、実際のファイル操作を実行する必要があります。

これにより、すべてのデータが1つのエグゼキュータに取り込まれるため、メモリの問題が発生する可能性があります。それはあなたが取るリスクです。

9
nod

@nodが言ったようにファイルに名前を付けることはできません。ただし、すぐにファイルの名前を変更することは可能です。 PySparkの使用例:

sc._jsc.hadoopConfiguration().set(
    "mapred.output.committer.class",
    "org.Apache.hadoop.mapred.FileOutputCommitter")
URI = sc._gateway.jvm.Java.net.URI
Path = sc._gateway.jvm.org.Apache.hadoop.fs.Path
FileSystem = sc._gateway.jvm.org.Apache.hadoop.fs.FileSystem
fs = FileSystem.get(URI("s3://{bucket_name}"), sc._jsc.hadoopConfiguration())
file_path = "s3://{bucket_name}/processed/source={source_name}/year={partition_year}/week={partition_week}/"
# remove data already stored if necessary
fs.delete(Path(file_path))

df.saveAsTextFile(file_path, compressionCodecClass="org.Apache.hadoop.io.compress.GzipCodec")

# rename created file
created_file_path = fs.globStatus(Path(file_path + "part*.gz"))[0].getPath()
fs.rename(
    created_file_path,
    Path(file_path + "{desired_name}.jl.gz"))
2
Juan Riaza