簡體   English   中英

如何覆蓋spark中的輸出目錄

[英]How to overwrite the output directory in spark

我有一個火花流應用程序,它每分鍾生成一個數據集。 我需要保存/覆蓋處理數據的結果。

當我試圖覆蓋數據集 org.apache.hadoop.mapred.FileAlreadyExistsException 時,會停止執行。

我設置了 Spark 屬性set("spark.files.overwrite","true") ,但沒有運氣。

如何覆蓋或預刪除 Spark 中的文件?

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

方便的皮條客:

implicit class PimpedStringRDD(rdd: RDD[String]) {
    def write(p: String)(implicit ss: SparkSession): Unit = {
      import ss.implicits._
      rdd.toDF().as[String].write.mode(SaveMode.Overwrite).text(p)
    }
  }

對於舊版本嘗試

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

在 1.1.0 中,您可以使用帶有 --conf 標志的 spark-submit 腳本來設置 conf 設置。

警告(舊版本):根據@piggybox 的說法,Spark 中存在一個錯誤,它只會覆蓋寫入它的part-文件所需的文件,任何其他文件都不會被刪除。

由於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")

參數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 => { } }

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

pyspark.sql.DataFrame.save文檔(當前為 1.3.1),您可以在保存 DataFrame 時指定mode='overwrite'

myDataFrame.save(path='myPath', source='parquet', mode='overwrite')

我已經驗證這甚至會刪除剩余的分區文件。 因此,如果您最初說 10 個分區/文件,然后用只有 6 個分區的 DataFrame 覆蓋文件夾,則生成的文件夾將包含 6 個分區/文件。

有關模式選項的更多信息,請參閱Spark SQL 文檔

df.write.mode('overwrite').parquet("/output/folder/path")如果您想使用 python 覆蓋鑲木地板文件,則該方法有效。 這是在火花 1.6.2 中。 API在以后的版本中可能會有所不同

  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)

這個保存功能的重載版本對我有用:

yourDF.save(outputPath, org.apache.spark.sql.SaveMode.valueOf("覆蓋"))

上面的示例將覆蓋現有文件夾。 savemode 也可以采用這些參數( https://spark.apache.org/docs/1.4.0/api/java/org/apache/spark/sql/SaveMode.html ):

Append : Append 模式是指在將 DataFrame 保存到數據源時,如果數據/表已經存在,則希望將 DataFrame 的內容附加到現有數據中。

ErrorIfExists : ErrorIfExists 模式意味着在將 DataFrame 保存到數據源時,如果數據已經存在,則預期會拋出異常。

Ignore :忽略模式是指在將DataFrame 保存到數據源時,如果數據已經存在,則保存操作預計不會保存DataFrame 的內容,也不會更改現有數據。

如果您願意使用自己的自定義輸出格式,您也可以使用 RDD 獲得所需的行為。

看看以下類: FileOutputFormatFileOutputCommitter

在文件輸出格式中,您有一個名為 checkOutputSpecs 的方法,用於檢查輸出目錄是否存在。 在 FileOutputCommitter 中有 commitJob,它通常將數據從臨時目錄傳輸到最終位置。

我還不能驗證它(只要我有幾分鍾的空閑時間就可以驗證)但理論上:如果我擴展 FileOutputFormat 並將 checkOutputSpecs 覆蓋到一個不會在目錄上拋出異常的方法已經存在,並調整我的自定義輸出提交者的 commitJob 方法來執行我想要的任何邏輯(例如覆蓋某些文件,附加其他文件),而不是我也可以使用 RDD 實現所需的行為。

輸出格式傳遞給:saveAsNewAPIHadoopFile(該方法也是調用 saveAsTextFile 以實際保存文件)。 並且輸出提交者是在應用程序級別配置的。

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("覆蓋").csv("/tmp/out/foldername")

除了覆蓋,SaveMode 還提供其他模式,如 SaveMode.Append、SaveMode.ErrorIfExists 和 SaveMode.Ignore

對於舊版本的 Spark,您可以使用以下命令用 RDD 內容覆蓋輸出目錄。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM