Pyspark通过键无分区写入多个输出

时间:2018-11-09 15:26:40

标签: python apache-spark pyspark

我有一个PySpark数据框,其中包含600万人的记录,每个记录都有一个单独的userid。每个userid有2000个条目。我想将每个userid的数据保存到一个以userid为名称的单独的csv文件中。

我有一些执行此操作的代码,taken from the solution to this question。但是,据我了解,代码将尝试对600万个ID进行分区。我实际上并不在乎这一点,因为我将把这些文件中的每一个写入另一个非HDFS服务器。

我应该注意,该代码仅可用于少量userids(最多3000个),但在全部600万个代码中均无法使用。

代码

output_file = '/path/to/some/hdfs/location'
myDF.write.partitionBy('userid').mode('overwrite').format("csv").save(output_file)

当我执行上述操作时,需要花费WEEKS才能运行,大部分时间都花在编写步骤上。我认为这是由于分区的数量。即使我手动将分区数指定为较小的值,执行仍然需要一定时间。

问题:是否有一种方法可以将每个userids数据保存到一个单独的,命名良好的(文件名= userid)文件中而不进行分区?

1 个答案:

答案 0 :(得分:1)

鉴于需求,确实有很大的改善希望。 HDFS并非设计用于处理非常小的文件,如果尝试同时打开600万个文件描述符,几乎所有文件系统都会面临挑战。

如果您还没有写,可以在写之前调用repartition:

(myDF
    .repartition('userid')
    .write.partitionBy('userid').mode('overwrite').format("csv").save(output_file))

如果每个文件可以接受多个ID,则可以使用持久性表和存储桶

myDFA
  .write
  .bucketBy(1024, 'userid')  # Adjust numBuckets if needed
  .sortBy('userid')
  .mode('overwrite').format("csv")
  .saveAsTable(output_table))

并分别处理每个文件,并获取连续的数据块。

最后,如果不是纯文本输出的硬性要求,则可以使用userid使用任何分片数据库和分区数据。