我有一個Spark Streaming(流式)應用程序,每分鍾產生一個數據集。我需要保存/覆蓋處理的數據的結果。
當我試圖覆蓋數據集時,拋異常org.apache.hadoop.mapred.FileAlreadyExistsException,然後停止執行。
我設置了Spark屬性set("spark.files.overwrite","true")
,但沒作用。
如何覆蓋或預先刪除Spark文件呢?
最佳解決思路
建議使用Dataframes
,加上類似... .write.mode(SaveMode.Overwrite) ...
的代碼。
對於舊版本嘗試
yourSparkConf.set("spark.hadoop.validateOutputSpecs", "false")
val sc = SparkContext(yourSparkConf)
在1.1.0中,您可以使用帶有–conf標誌的spark-submit腳本來設置conf設置。
次佳解決思路
參數spark.files.overwrite
的意思:“當目標文件存在且其內容與源不匹配時,是否覆蓋通過SparkContext.addFile()
添加的文件”。所以它對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 => { } }
第三種解決思路
從pyspark.sql.DataFrame.save文檔來看(當前位於1.3.1),可以在保存DataFrame時指定mode='overwrite'
:
myDataFrame.save(path='myPath', source='parquet', mode='overwrite')
經證實,這甚至會刪除分區文件。因此,如果您最初說了10個分區/文件,然後用隻有6個分區的DataFrame覆蓋了該文件夾,則生成的文件夾將具有6個分區/文件。
有關模式選項的更多信息,請參閱Spark SQL documentation。
第四種思路
由於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
‘source’可以是(“com.databricks.spark.avro” | “parquet” | “json”)