存储在 S3 中时正确的 Parquet 文件大小?

Correct Parquet file size when storing in S3?

我一直在阅读关于这个主题和几个论坛的几个问题,在所有这些论坛中,他们似乎都提到从 Spark 生成的每个 .parquet 文件应该是 64MB 或 1GB 大小,但是我仍然无法确定哪种情况属于这些文件大小,以及除了 HDFS 将它们拆分为 64MB 块之外的原因。

我目前的测试场景如下。

dataset
  .coalesce(n) # being 'n' 4 or 48 - reasons explained below.
  .write
  .mode(SaveMode.Append)
  .partitionBy(CONSTANTS)
  .option("basepath", outputPath)
  .parquet(outputPath)

我目前总共处理 2.5GB 到 3GB 的日常数据,这些数据将被拆分并保存到每年的每日存储桶中。 之所以'n'是4或48只是为了测试目的,因为我提前知道我的测试集的大小,我尝试得到一个接近64MB的数字或 1GB,我可以。在获得之前保存所需的确切大小之前,我还没有实现代码来缓冲所需的数据。

所以我的问题是...

如果我不打算使用 HDFS 而只是从 S3 存储和检索数据,我是否应该考虑那么多的大小?

此外,如果我打算使用 HDFS 来存储我生成的 .parquet 文件,对于大约 10GB 最大 的日常数据集,哪个应该是最佳大小?

任何其他优化提示将不胜感激!

您可以控制 parquet 文件的拆分大小,前提是您使用像 snappy 这样的可拆分压缩来保存它们。对于 s3a 连接器,只需将 fs.s3a.block.size 设置为不同的字节数。

较小的拆分大小

  • 更多的工作人员可以同时处理一个文件。如果您有闲置工人,请加快速度。
  • 更多的启动开销调度工作,开始处理,提交任务
  • 从输出中创建更多文件,除非您重新分区。

小文件与大文件

小文件:

  • 无论你是否想要,你都会得到那个小的分裂。
  • 即使你使用不可分割的压缩。
  • 列出文件需要更长的时间。在 s3 上列出目录树非常慢
  • 不可能要求比文件长度更大的块大小
  • 如果您的 s3 客户端不在块中执行增量写入,则更容易保存。 (如果您设置 spark.hadoop.fs.s3a.fast.upload true,Hadoop 2.8+ 会执行。

就我个人而言,这是个人观点,并且是一些基准驱动的 - 但与您的查询无关

写作

  • 保存到更大的文件。
  • 活泼。
  • 较深较窄的目录树较浅+较宽

阅读

  • 玩不同的块大小;将 32-64 MB 视为最小值
  • Hadoop 3.1,使用零重命名提交者。否则,切换到 v2
  • 如果您的 FS 连接器支持此功能,请确保打开随机 IO (hadoop-2.8 + spark.hadoop.fs.s3a.experimental.fadvise random
  • 通过 .repartion() 保存到更大的文件。
  • 留意您收集了多少数据,因为存储大量旧数据很容易运行增加大额账单。

另见 Improving Spark Performance with S3/ADLS/WASB