如何在spark中使用saveAsTextFile命名文件?

时间:2015-11-11 21:15:34

标签: apache-spark pyspark rdd

在spark版本1.5.1中保存为文本文件时,我使用:rdd.saveAsTextFile('<drectory>')

但如果我想在该目录中找到该文件,我如何将其命名为我想要的名称?

目前,我认为它名为part-00000,必须是默认值。我该如何命名?

3 个答案:

答案 0 :(得分:8)

这个问题的正确答案是saveAsTextFile不允许您命名实际文件。

这样做的原因是数据被分区并且在作为saveAsTextFile(...)调用的参数给出的路径内,它会将其视为目录,然后为每个分区写一个文件。

您可以致电rdd.coalesce(1).saveAsTextFile('/some/path/somewhere'),它会创建/some/path/somewhere/part-0000.txt

如果您需要更多控制权,那么在执行rdd.collect()之后,您需要在结束时进行实际的文件操作。

注意,这会将所有数据拉入一个执行程序,因此您可能会遇到内存问题。这就是你冒的风险。

答案 1 :(得分:7)

正如我在上面的评论中所说,可以找到带有示例的文档here。并引用方法saveAsTextFile的描述:

  

使用元素的字符串表示将此RDD保存为文本文件。

在下面的示例中,我将一个简单的RDD保存到文件中,然后加载它并打印其内容。

samples = sc.parallelize([
    ("abonsanto@fakemail.com", "Alberto", "Bonsanto"),
    ("mbonsanto@fakemail.com", "Miguel", "Bonsanto"),
    ("stranger@fakemail.com", "Stranger", "Weirdo"),
    ("dbonsanto@fakemail.com", "Dakota", "Bonsanto")
])

print samples.collect()

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

read_rdd.collect()

输出

('abonsanto@fakemail.com', 'Alberto', 'Bonsanto')
('mbonsanto@fakemail.com', 'Miguel', 'Bonsanto')
('stranger@fakemail.com', 'Stranger', 'Weirdo')
('dbonsanto@fakemail.com', 'Dakota', 'Bonsanto')

[u"('abonsanto@fakemail.com', 'Alberto', 'Bonsanto')",
 u"('mbonsanto@fakemail.com', 'Miguel', 'Bonsanto')",
 u"('stranger@fakemail.com', 'Stranger', 'Weirdo')",
 u"('dbonsanto@fakemail.com', 'Dakota', 'Bonsanto')"]

让我们看看使用基于Unix的终端。

usr@host:~/folder/here.txt$ cat *
('abonsanto@fakemail.com', 'Alberto', 'Bonsanto')
('mbonsanto@fakemail.com', 'Miguel', 'Bonsanto')
('stranger@fakemail.com', 'Stranger', 'Weirdo')
('dbonsanto@fakemail.com', 'Dakota', 'Bonsanto')

答案 2 :(得分:2)

不能像@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"))