无论如何将火花分区写入不同的子路径?

Posted

技术标签:

【中文标题】无论如何将火花分区写入不同的子路径?【英文标题】:Anyway to write spark partitions into different sub-paths? 【发布时间】:2019-12-25 04:02:03 【问题描述】:

当我使用时

df.repartition(100).write.mode('overwrite').json(output_path)

Spark 将在 'output_path' 指定的同一路径下写入 100 个 json 文件。 是否可以将分区写入不同的子目录?比如前10个分区写入'output_path/01/',后10个分区写入'output_path/02',以此类推?

不限于此方案。我只需要避免将所有输出数据写入同一路径;我需要对数据框进行分区并将它们写入不同的子文件夹。


这个问题的动机是,我使用的是 AWS s3,每当我在同一路径下写入所有数据时,都会出现“SLOW DOWN”错误。我被告知写入速度限制是“基于前缀”的,也就是说,如果我将所有数据写入

s3://someurl/

然后我会收到一个 SLOW DOWN 错误。相反,我需要将一些数据写入 s3://someurl/01/,将一些数据写入 s3://someurl/02/ 和 s3://someurl/03/,...我需要帮助如何实现这一点.


当然,解决这个问题的一种方法是使用where手动分离数据;但我希望有一些内置机制可以更优雅地解决这个问题。谢谢!

【问题讨论】:

【参考方案1】:

您可以添加一个虚拟分区列,例如

from pyspark.sql import functions as F
df = df.withColumn("dummy", F.floor(F.rand() * 10))
df.write.partitionBy("dummy").mode('overwrite').json(output_path)

这将生成以下路径:

s3://someurl/dummy=0/
s3://someurl/dummy=1/
s3://someurl/dummy=2/
...

不利的一面是,您在阅读时会多出一列

【讨论】:

以上是关于无论如何将火花分区写入不同的子路径?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Apache Beam Python 将输出写入动态路径

将分区(火花)镶木地板加载到 bigquery 表

批处理 - 如何将文件类型 A 的文件从路径 A 的子文件夹 A 复制到路径 B 的子文件夹 A?

包含子文件夹的文件夹顶部的分区表,其中包含火花中的 json 文件

如何使用替换 Where 子句实现以下火花行为

编译安装的mysql如何更改文件路径