我有一个火花流应用程序,可以为每分钟生成一个数据集。 我需要保存/覆盖已处理数据的结果。
当我试图覆盖数据集org.apache.hadoop.mapred.FileAlreadyExistsException时会停止执行。
我设置了Spark属性set("spark.files.overwrite","true")
,但没有运气。
如何覆盖或预先删除spark中的文件?
答案 0 :(得分:87)
更新:建议使用Dataframes
,加上... .write.mode(SaveMode.Overwrite) ...
。
对于旧版本,请尝试
yourSparkConf.set("spark.hadoop.validateOutputSpecs", "false")
val sc = SparkContext(yourSparkConf)
在1.1.0中,您可以使用带有--conf标志的spark-submit脚本设置conf设置。
警告(旧版本):根据@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 => { } }
答案 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获得所需的行为。
查看以下课程: FileOutputFormat, FileOutputCommitter
在文件输出格式中,您有一个名为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)