如何使saveAsTextFile不将输出分割成多个文件?

在Spark中使用Scala时,每当使用saveAsTextFile转储结果时,它似乎将输出分成多个部分。 我只是传递一个参数(path)。

 val year = sc.textFile("apat63_99.txt").map(_.split(",")(1)).flatMap(_.split(",")).map((_,1)).reduceByKey((_+_)).map(_.swap) year.saveAsTextFile("year") 
  1. 输出的数量是否与它使用的减速器的数量相对应?
  2. 这是否意味着输出被压缩?
  3. 我知道我可以使用bash将输出组合在一起,但有没有一个选项可以将输出存储在单个文本文件中,而不会分裂? 我看了一下API文档,但是没有多说这个。

它将其保存为多个文件的原因是因为计算是分布式的。 如果输出足够小,以至于你认为你可以把它放在一台机器上,那么你可以结束你的程序

 val arr = year.collect() 

然后将结果数组保存为一个文件,另一种方法是使用自定义分区程序partitionBy ,并将其设置为一切进入一个分区,尽pipe这不是可取的,因为您不会得到任何并行化。

如果您需要使用saveAsTextFile保存文件,则可以使用coalesce(1,true).saveAsTextFile() 。 这主要意味着做计算然后合并到1分区。 你也可以使用repartition(1) ,它只是一个包装器,用于将shuffle参数设置为true。 通过RDD.scala的源头来看 ,我是如何看待这些东西的大部分,你应该看看。

你可以调用coalesce(1)然后saveAsTextFile() – 但是如果你有很多数据,这可能是一个坏主意。 为了让单独的映射器和简化器写入不同的文件,就像在Hadoop中一样生成每个拆分文件的单独文件。 如果你的数据非常less,那么只有一个输出文件是个好主意,在这种情况下,你也可以使用collect(),就像@aaronman所说的那样。

你可以在下一个版本的Spark中使用它,在当前的版本1.0.0中,除非你用某种方式进行手动操作,例如,像你提到的那样用bash脚本调用。

在Spark 1.6.1中,格式如下所示。 它会创build一个单一的输出文件。如果输出足够小,最好使用它。基本上,它会返回一个新的RDD,并将其减less到numPartition分区。如果您正在进行剧烈的聚合,例如numPartitions = 1,这可能会导致您的计算发生在比您喜欢的节点更less的节点上(例如numPartitions = 1时的一个节点)

 pair_result.coalesce(1).saveAsTextFile("/app/data/") 

正如其他人所提到的,您可以收集或合并您的数据集,以强制Spark生成单个文件。 但是这也限制了并行处理数据集的Spark任务的数量。 我更喜欢让它在输出HDFS目录中创build一百个文件,然后使用hadoop fs -getmerge /hdfs/dir /local/file.txt将结果提取到本地文件系统中的单个文件中。 当你的输出是一个相对较小的报告时,这是最有意义的。

我还想提一下,文档中明确指出,用真正的less量分区调用coalesce时,用户应该小心。 这可能会导致上游分区inheritance这个数量的分区。

除非真正需要,否则我不会推荐使用coalesce(1)。

这是我的答案输出一个单一的文件。 我刚刚添加coalesce(1)

 val year = sc.textFile("apat63_99.txt") .map(_.split(",")(1)) .flatMap(_.split(",")) .map((_,1)) .reduceByKey((_+_)).map(_.swap) year.saveAsTextFile("year") 

码:

 year.coalesce(1).saveAsTextFile("year")