覆盖实木复合地板文件会在Spark中引发异常

时间:2018-09-04 07:08:12

标签: scala apache-spark dataframe hdfs

我正在尝试从hdfs位置读取镶木地板文件,进行一些转换并在同一位置覆盖该文件。我必须在同一位置覆盖文件,因为必须多次运行相同的代码。

这是我编写的代码

val df = spark.read.option("header", "true").option("inferSchema", "true").parquet("hdfs://master:8020/persist/local/")
//after applying some transformations lets say the final dataframe is transDF which I want to overwrite at the same location.
transDF.write.mode("overwrite").parquet("hdfs://master:8020/persist/local/")

现在问题出在从给定位置读取镶木地板文件之前,出于某种原因引发火花,我相信由于覆盖模式,它会删除给定位置的文件。因此,在执行代码时,出现以下错误。

File does not exist: hdfs://master:8020/persist/local/part-00000-e73c4dfd-d008-4007-8274-d445bdea3fc8-c000.snappy.parquet

关于如何解决此问题的任何建议?谢谢。

2 个答案:

答案 0 :(得分:3)

简单的答案是您不能覆盖正在阅读的内容。其背后的原因是覆盖将需要删除所有内容,但是,由于spark并行运行,因此某些部分可能仍在读取中。此外,即使读取了所有内容,spark也需要原始文件来重新计算失败的任务。

由于需要多次迭代的输入,因此我只需将输入名称和输出作为执行一次迭代的函数的参数,并仅在写入成功后才删除前一次迭代。

答案 1 :(得分:-1)

这是我尝试过的并且有效的方法。我的要求几乎是相同的。这是upsert选项。

顺便说一下,

设置了spark.conf.set('spark.sql.sources.partitionOverwriteMode','dynamic')属性。即使那样,转换作业也失败了

  1. 在每次批量操作之前备份S3文件夹(最终策划层)
  2. 使用数据框操作,先删除S3实木复合地板文件位置,然后再覆盖
  3. 然后附加到特定位置

以前,整个作业的运行时间为1.5小时,并且经常失败。现在整个操作要花10到15分钟