当前位置: 首页 > 知识库问答 >
问题:

Spark-写入128 MB大小的镶木地板文件

满才
2023-03-14

我有一个超过10亿行的DataFrame(df)

df.coalesce(5)
.write
.partitionBy("Country", "Date")
.mode("append")
.parquet(datalake_output_path)

从上面的命令中,我了解到我的100个工作节点集群(spark 2.4.5)中只有5个工作节点将执行所有任务。使用聚结剂(5)需要7小时才能完成。

我应该尝试< code >重新分区而不是< code >联合?

有没有一种更快速/高效的方法来写出128 MB大小的拼花文件,或者我需要首先计算数据帧的大小来确定需要多少分区。

例如,如果我的数据帧大小为1 GB,spark.sql.files。maxPartitionBytes=128MB是否应该首先计算否。需要的分区数为1 GB/128 MB=大约(8),然后进行重新分区(8)或合并(8)?

这个想法是在编写时最大限度地扩大输出中镶木地板文件的大小,并且能够快速(更快)做到这一点。

共有2个答案

周良弼
2023-03-14

如果您从较高的分区数到较低的分区数,则合并会更好。但是,如果在编写df之前,您的代码没有进行混洗,那么合并将被推到DAG中可能的最早点。您可以做的是在100个分区或任何您认为合适的数字中处理您的df,然后在编写df之前将其持久化。然后使用coalesce将分区减少到5个并写入。这可能会给你更好的表现

屠建本
2023-03-14

您可以获取数据帧< code>df的大小(< code>dfSizeDiskMB),方法是保存它,然后检查Web UI上的存储选项卡,如本答案所示。有了这些信息和预期的Parquet压缩率的估计值,您就可以估计要达到您想要的输出文件分区大小所需的分区数量

val targetOutputPartitionSizeMB = 128
val parquetCompressionRation = 0.1
val numOutputPartitions = dfSizeDiskMB * parquetCompressionRatio / targetOutputPartitionSizeMB
df.coalesce(numOutputPartitions).write.parquet(path)

请注意,<code>spark.files。maxPartitionBytes在这里不相关,因为它是:

读取文件时打包到单个分区中的最大字节数。

(除非 df 是在未创建中间数据帧的情况下读取输入数据源的直接结果。df 的分区数更有可能由 spark.sql.shuffle.partitions 决定,即 Spark 用于从联接和聚合创建的数据帧的分区数)。

我应该尝试重新分区而不是合并吗?

< code>coalesce通常更好,因为它可以避免与< code>repartition相关的混乱,但请注意文档中的警告,即根据您的使用情况,上游阶段可能会失去并行性。

 类似资料:
  • 我对火花有点陌生。在我的spark calc完成后,我目前在amazon s3上看到一些奇怪的缓慢的拼花。 写一个小文件需要1.8小时(写时有2个分区) 我用一个不同的更大的文件(更多行更多列)运行了相同的spark calc(编写时有3个分区) 写入调用本身:

  • 我通过两种方法生成拼花地板文件:动弹消防软管和火花作业。它们都被写入S3上相同的分区结构中。两组数据都可以使用相同的Athena表定义进行查询。两者都使用gzip压缩。 然而,我注意到Spark生成的拼花地板文件大约是Firehose生成的拼花地板文件的3倍大。有什么理由会这样吗?在使用Pyarrow加载模式和元数据时,我确实注意到了一些差异: 模式差异可能是罪魁祸首吗?还有别的原因吗? 这两个特

  • 我一直在阅读有关此主题的一些问题以及几个论坛,并且在所有这些论坛中,他们似乎都提到从Spark中产生的每个. parket文件应该是64MB或1GB大小,但仍然无法让我想到哪些案例场景属于每个这些文件大小以及除了HDFS将它们拆分为64MB块之外的原因。 我当前的测试场景如下。 我目前每天处理2.5GB到3GB的数据,这些数据每年将被拆分并保存到每日存储桶中。n等于4或48的原因只是为了测试,因为

  • 我有一个数据帧,它是由运行特定日期的每日批处理创建的,然后保存在HDFS(Azure Data Lake Gen 2)中。 它是用这样的东西保存的 如您所见,我没有对数据帧进行分区,因为它只包含一个日期。 例如,第一天的第一个文件将存储在文件夹中 交易/2019/08/25 然后第二天,它就会在文件夹里 贸易/2019/08/26 问题是,当所有数据都放好后,日期上的过滤器谓词是否仍会被按下,HD

  • 问题内容: 有没有办法从Java创建镶木地板文件? 我的内存中有数据(java类),我想将其写入一个Parquet文件中,以便以后从apache-drill中读取它。 有没有简单的方法可以做到这一点,例如将数据插入sql表? 得到它了 谢谢您的帮助。 结合答案和此链接,我能够创建一个实木复合地板文件并用钻头将其读回。 问题答案: 不建议使用ParquetWriter的构造函数(1.8.1),但不建

  • 我无法使用镶木地板文件将列的类型从更改为。 使用: 改变表DATABASE.TABLE改变COL INT(从字符串到int) 或 < code >更改表数据库。表格更改列列字符串(从int到string) 读取数据时产生错误: 文件x的“db.table.col”列具有不兼容的拼花架构。列类型:INT,拼花模式:可选byte_array col[i:1 d:1 r:0] 读了这个留档,我明白: T