Spark - 读取和写入相同的 S3 位置

Posted

技术标签:

【中文标题】Spark - 读取和写入相同的 S3 位置【英文标题】:Spark - Read and Write back to same S3 location 【发布时间】:2019-10-13 10:03:00 【问题描述】:

我正在从 S3 位置读取数据集 dataset1 和 dataset2。然后我对它们进行转换并写回从数据集2读取的相同位置。

但是,我收到以下错误消息:

An error occurred while calling o118.save. No such file or directory 's3://<myPrefix>/part-00001-a123a120-7d11-581a-b9df-bc53076d57894-c000.snappy.parquet

如果我尝试写入新的 S3 位置,例如s3://dataset_new_path.../ 然后代码可以正常工作。

my_df \
  .write.mode('overwrite') \
  .format('parquet') \
  .save(s3_target_location)

注意:我在读取数据框后尝试使用.cache(),但仍然出现相同的错误。

【问题讨论】:

【参考方案1】:

这导致问题的原因是您正在读取和写入您尝试覆盖的同一路径。这是标准的 Spark 问题,与 AWS Glue 无关。

Spark 在 DF 上使用惰性转换,并在调用特定操作时触发。它创建 DAG 以保存有关应应用于 DF 的所有转换的信息。

当您从同一位置读取数据并使用覆盖写入时,“使用覆盖写入”是 DF 的操作。当 spark 看到“使用覆盖写入”时,它会在它的执行计划中添加先删除路径,然后尝试读取已经空置的路径;因此错误。

可能的解决方法是先写入某个临时位置,然后将其用作源,覆盖dataset2 位置

【讨论】:

只是为了澄清“可能的解决方法是先写入某个临时位置,然后将其用作源,在 dataset2 位置覆盖”=> 将临时数据存储在文件夹中,而不是作为子文件夹你在哪里工作。 1. 从 root/mytempfolder 读取 2. 进行数据转换 3. 将转换后的数据写入 root/mytempfolder 4. 从 root/mytempfolder 读取 5. 写入 root/myfolder

以上是关于Spark - 读取和写入相同的 S3 位置的主要内容,如果未能解决你的问题,请参考以下文章

将大文件写入 S3 的最佳方法是啥?

使用 Spark 通过 s3a 将 parquet 文件写入 s3 非常慢

如何使用 spark(scala)读取和写入(更新)同一个文件

spark sql 无法在 S3 中查询镶木地板分区

来自 EMR/Spark 的 S3 写入时间极慢

使用 403 写入 S3 时,在 EMR 上运行的 Spark 偶尔会失败