Amazon s3 pyspark在输出中写入大量较小的文件

Amazon s3 pyspark在输出中写入大量较小的文件,amazon-s3,pyspark,amazon-athena,Amazon S3,Pyspark,Amazon Athena,我正在使用pyspark处理一些数据,并将输出写入S3。我在雅典娜创建了一个表,用于查询这些数据 数据是json字符串的形式(每行一个),spark代码读取文件,根据特定字段对其进行分区,然后写入S3 对于1.1 GB的文件,我看到spark正在编写36个文件,每个文件大小大约5 MB。阅读athena文档时,我发现最佳文件大小为~128MB 为什么spark要写这么小的文件。有没有办法控制文件大小 有没有办法控制文件大小 有一些控制机制。然而,它们并不明确 s3驱动程序不是spark本身的一部

我正在使用pyspark处理一些数据,并将输出写入S3。我在雅典娜创建了一个表,用于查询这些数据

数据是json字符串的形式(每行一个),spark代码读取文件,根据特定字段对其进行分区,然后写入S3

对于1.1 GB的文件,我看到spark正在编写36个文件,每个文件大小大约5 MB。阅读athena文档时,我发现最佳文件大小为~128MB

为什么spark要写这么小的文件。有没有办法控制文件大小

有没有办法控制文件大小

有一些控制机制。然而,它们并不明确

s3驱动程序不是spark本身的一部分。它们是hadoop安装的一部分,随spark emr一起提供。s3块大小可以在
/etc/hadoop/core site.xml

但是,默认情况下,它应该是128MB左右

spark为什么要写这么小的文件

Spark将遵循hadoop块大小。但是,您可以在编写之前使用
partionBy

假设您使用
partionBy(“date”).write.csv(“s3://products/”)
。 Spark将为每个分区创建一个子文件夹,其中包含
日期
。在内部 每个分区文件夹spark将再次尝试创建块,并尝试遵守
fs.s3a.block.size

e、 g

在上面的例子中,一个特定的分区可以小于128mb的块大小

因此,只需在
/etc/hadoop/core site.xml中仔细检查块大小,以及在编写之前是否需要使用
partitionBy
对数据帧进行分区

编辑:

还建议重新划分数据帧,以匹配
partitionBy
方案

df.repartition('field1','field2','field3')
.write.partitionBy('field1','field2','field3')

writer.partitionBy
对现有数据帧分区进行操作。它不会
重新分区
原始数据帧。因此,如果对整个数据帧进行了不同的分区,则会发生嵌套分区。

您能否将pyspark代码与pyspark作业的源代码一起发布?这是否回答了您的问题@很酷,这更像是一项工作。我重新分区了数据并限制了文件大小。我知道平均记录大小。基于此,我将maxRecordsPerFile设置为保持文件大小无限增长。@cool是的。这足以限制文件的数量。现在,仅当没有超过指定数量的记录时,才会创建新文件。我用这些代码创建了一个要点。看看它是否有帮助@Kapil再次感谢,这会有帮助的。也许您可以自己在回答中详细阐述这一讨论,并将其标记为已接受,这只是为了解决问题。尽管完整的数据对应于单个分区,但文件大小仍然不是128。我在core-site.xml中没有任何条目,因此假设它采用默认大小,但在更新多部分上载的属性后,没有任何更改您是否检查了hadoop s3 conf?什么是s3 block.size?当我检查spark emr hadoop conf时,根本没有设置s3 block.size。我们写的文件大约有150MB。执行
cd/etc/hadoop/conf/
然后运行
grep-rni“s3”*
检查是否存在
block.size
设置刚才还看到,我们重新划分数据帧以匹配datawriter模式。在答案中添加了另一个提示
s3:/products/date=20191127/00000.csv
s3:/products/date=20191127/00001.csv
s3:/products/date=20200101/00000.csv
df.repartition('field1','field2','field3')
.write.partitionBy('field1','field2','field3')