【问题标题】:FileNotFoundException when trying to save DataFrame to parquet format, with 'overwrite' mode尝试使用“覆盖”模式将 DataFrame 保存为镶木地板格式时出现 FileNotFoundException
【发布时间】:2017-07-25 06:12:02
【问题描述】:

我有这个奇怪的错误。我有一个例程,如果数据帧存在(或创建一个数据帧),则读取它,对其进行修改,然后以镶木地板格式再次将其保存在同一目标路径中,并使用“覆盖”模式。

在第一次运行时,当没有数据框时,我创建一个并保存它。它在输出文件夹中生成 4 个文件:

  • _SUCCESS.crc
  • part-r-<.....>.snappy.parquet.crc
  • _成功
  • part-r-<.....>.snappy.parquet

然后,在第二次运行中,我读取了数据帧,对其进行了修改,当我尝试覆盖它时,它抛出了一个异常,*part-r-&lt;.....&gt;.snappy.parquet file does not exist*.

异常发生时输出文件夹为空,但在df.write.parquet(path, 'overwrite')执行之前文件夹中包含该文件。

我尝试将 spark.sql.cacheMetadata 设置为“false”,但没有帮助。 spark.catalog.listTables() 返回一个空列表,因此没有必要刷新任何内容。

现在,我只是删除输出文件夹的项目,然后写入数据框。有用。但是为什么原来的“覆盖”模式会失败??

谢谢。

【问题讨论】:

  • 问题是当你应用 savemode 作为覆盖然后在创建物理计划 spark 后删除目录你可以尝试 savemode as append
  • 我面临同样的问题和保存模式,因为从 spark 写入 s3 时追加也失败

标签: apache-spark pyspark apache-spark-sql


【解决方案1】:

RDD 不保存变量之类的数据,它只是一个数据结构,知道如何获取数据(getPartition)以及在调用 action 时对该数据执行什么转换(计算)。

所以你在这里做的是,

第一次 => ... => 保存到路径 A
第二次以后 => 从路径 A 读取 => 进行一些转换 => 使用覆盖模式保存到路径 A

现在请注意,您的实际操作是 Save to path A 。在你调用一个动作之前,Spark 只创建 DAG,它知道何时调用一个动作到哪里查找数据(保存到路径 A)、如何转换它们以及在哪里保存/显示。

但是当您选择模式覆盖时,Spark 在它的执行计划中首先添加删除路径,然后尝试读取已经空置的路径。

因此,作为一种解决方法,您可以将它们保存在不同的文件夹(如分区基础)中,或者您可以将它们保存在两个路径中,一个目标和一个 tmp。

【讨论】:

  • 我也面临同样的问题。我所做的是将它写入一个临时位置,然后从那里读取并写入主要位置。它仍然失败。有什么想法吗 ?提前致谢。
  • 为什么会有这种行为? Spark 在创建计划时应该意识到这种不一致。
【解决方案2】:

这里要做的另一件事是缓存它 -

df.cache()

在你从 hdfs 读取它之后。

【讨论】:

  • AFAIK,cache() 不是一个动作,因此它不会触发 Spark 评估。
  • 对我不起作用,spark 仍然看起来会从刚刚删除的文件中读取,因为覆盖。
猜你喜欢
  • 2019-09-02
  • 1970-01-01
  • 2016-10-05
  • 1970-01-01
  • 2020-02-25
  • 1970-01-01
  • 2021-03-15
  • 1970-01-01
  • 2019-11-19
相关资源
最近更新 更多