如何覆盖spark中的输出目录

时间:2014-11-20 07:14:23

标签: apache-spark

我有一个火花流应用程序,可以为每分钟生成一个数据集。 我需要保存/覆盖已处理数据的结果。

当我试图覆盖数据集org.apache.hadoop.mapred.FileAlreadyExistsException时会停止执行。

我设置了Spark属性set("spark.files.overwrite","true"),但没有运气。

如何覆盖或预先删除spark中的文件?

8 个答案:

答案 0 :(得分:87)

更新:建议使用Dataframes,加上... .write.mode(SaveMode.Overwrite) ...

对于旧版本,请尝试

yourSparkConf.set("spark.hadoop.validateOutputSpecs", "false")
val sc = SparkContext(yourSparkConf)

在1.1.0中,您可以使用带有--conf标志的spark-submit脚本设置co​​nf设置。

警告(旧版本):根据@piggybox,Spark中存在一个错误,它只会覆盖写入part-文件所需的文件,任何其他文件都将被删除。

答案 1 :(得分:25)

参数spark.files.overwrite的文档说明了这一点:"当目标文件存在且其内容与源文件的内容不匹配时,是否覆盖通过SparkContext.addFile()添加的文件。&#34 ;所以它对saveAsTextFiles方法没有影响。

您可以在保存文件之前执行此操作:

val hadoopConf = new org.apache.hadoop.conf.Configuration()
val hdfs = org.apache.hadoop.fs.FileSystem.get(new java.net.URI("hdfs://localhost:9000"), hadoopConf)
try { hdfs.delete(new org.apache.hadoop.fs.Path(filepath), true) } catch { case _ : Throwable => { } }

Aas在此解释: http://apache-spark-user-list.1001560.n3.nabble.com/How-can-I-make-Spark-1-0-saveAsTextFile-to-overwrite-existing-file-td6696.html

答案 2 :(得分:23)

,因为df.save(path, source, mode)已被弃用,(http://spark.apache.org/docs/1.5.0/api/scala/index.html#org.apache.spark.sql.DataFrame

使用df.write.format(source).mode("overwrite").save(path)
其中df.write是DataFrameWriter

'源'可以(" com.databricks.spark.avro" |"镶木地板" |" json")

答案 3 :(得分:5)

df.write.mode('overwrite')。parquet(“/ output / folder / path”)如果你想用python覆盖一个镶木地板文件,它可以工作。这是火花1.6.2。 API可能在以后的版本中有所不同

答案 4 :(得分:4)

  val jobName = "WordCount";
  //overwrite the output directory in spark  set("spark.hadoop.validateOutputSpecs", "false")
  val conf = new 
  SparkConf().setAppName(jobName).set("spark.hadoop.validateOutputSpecs", "false");
  val sc = new SparkContext(conf)

答案 5 :(得分:2)

保存功能的这个重载版本适用于我:

yourDF.save(outputPath,org.apache.spark.sql.SaveMode.valueOf(“Overwrite”))

上面的示例将覆盖现有文件夹。 savemode也可以采用这些参数(https://spark.apache.org/docs/1.4.0/api/java/org/apache/spark/sql/SaveMode.html):

追加:追加模式意味着在将DataFrame保存到数据源时,如果数据/表已经存在,则DataFrame的内容应该附加到现有数据。

ErrorIfExists :ErrorIfExists模式意味着在将DataFrame保存到数据源时,如果数据已经存在,则会引发异常。

忽略:忽略模式意味着在将DataFrame保存到数据源时,如果数据已存在,则保存操作不会保存DataFrame的内容并且不会更改现有数据

答案 6 :(得分:0)

如果您愿意使用自己的自定义输出格式,您也可以使用RDD获得所需的行为。

查看以下课程: FileOutputFormatFileOutputCommitter

在文件输出格式中,您有一个名为checkOutputSpecs的方法,该方法检查输出目录是否存在。 在FileOutputCommitter中,您有commitJob,它通常将数据从临时目录传输到最终位置。

我还没有能够验证它(只要我有很少的免费分钟就会这样做)但理论上:如果我扩展FileOutputFormat并将checkOutputSpecs覆盖到一个不会抛出异常的方法目录已经存在,并调整我的自定义输出提交器的commitJob方法来执行我想要的逻辑(例如,覆盖一些文件,附加其他文件),而不是我可以用RDD实现所需的行为。

输出格式传递给:saveAsNewAPIHadoopFile(也称为saveAsTextFile方法,用于实际保存文件)。输出提交器在应用程序级别配置。

答案 7 :(得分:0)

Spark – 覆盖输出目录:

Spark 默认不会覆盖 S3、HDFS 和任何其他文件系统上的输出目录,当您尝试将 DataFrame 内容写入现有目录时,Spark 会因此返回运行时错误。为了克服这个问题,Spark 提供了一个枚举 org.apache.spark.sql.SaveMode.Overwrite 来覆盖现有文件夹。

例如,我们需要将此 Overwrite 用作 DataFrameWrite 类的 mode() 函数的参数。

df。 write.mode(SaveMode.Overwrite).csv("/tmp/out/foldername")

或者你可以使用覆盖字符串。

df.write.mode("overwrite").csv("/tmp/out/foldername")

除了覆盖之外,SaveMode 还提供其他模式,如 SaveMode.Append、SaveMode.ErrorIfExists 和 SaveMode.Ignore

对于旧版本的 Spark,您可以使用以下命令用 RDD 内容覆盖输出目录。

sparkConf.set("spark.hadoop.validateOutputSpecs", "false") val sparkContext = SparkContext(sparkConf)