स्पार्क में आउटपुट डायरेक्टरी को ओवरराइट कैसे करें


107

मेरे पास एक स्पार्क स्ट्रीमिंग एप्लिकेशन है जो हर मिनट के लिए डेटासेट बनाता है। मुझे संसाधित डेटा के परिणामों को सहेजने / अधिलेखित करने की आवश्यकता है।

जब मैंने डेटासेट को अधिलेखित करने की कोशिश की। org.apache.hadoop.mapred.FileAlreadyExistsException निष्पादन बंद कर देता है।

मैंने स्पार्क संपत्ति निर्धारित की set("spark.files.overwrite","true"), लेकिन कोई भाग्य नहीं है।

कैसे चिंगारी से फ़ाइलों को अधिलेखित या प्रेडिकेट करें?


1
हाँ, यह बेकार है यह नहीं है, मैं इसे एक प्रतिगमन 0.9.0 करने के लिए प्रतिगमन मानता हूं। कृपया मेरा उत्तर
मानें

set("spark.files.overwrite","true")केवल उन फाइलों के लिए काम करता है spark.addFile()
जिन्हें

जवाबों:


106

अद्यतन: सुझाव का उपयोग कर 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 फ्लैग के साथ स्पार्क-सबमिट स्क्रिप्ट का उपयोग कर कन्फ्यूजन सेट कर सकते हैं।

चेतावनी (पुराने संस्करण): @piggybox के अनुसार स्पार्क में एक बग है जहां यह केवल फाइलों को अधिलेखित कर देगा इसे लिखने की जरूरत है part-फाइलें, किसी भी अन्य फ़ाइलों को छोड़ दिया जाएगा।


29
के लिए Spark 1.4:df.write.mode(SaveMode.Overwrite).parquet(path)
हा फाम

स्पार्क एसक्यूएल के लिए, आपके पास कोर स्पार्क के लिए सेवमोड को परिभाषित करने के विकल्प हैं, आपके पास ऐसा कुछ भी नहीं है। वास्तव में saveAsTextFile और अन्य परिवर्तनों के लिए उस तरह की सुविधा में से कुछ करना चाहते हैं
मुर्तजा कांचवाला

3
एक छिपी हुई समस्या: HDFS के माध्यम से पूरे फ़ोल्डर को मिटा देने के लिए @ pzecevic के समाधान की तुलना, इस दृष्टिकोण में स्पार्क केवल आउटपुट फ़ोल्डर में एक ही फ़ाइल नाम के साथ भाग फ़ाइलों को अधिलेखित करेगा। यह ज्यादातर समय काम करता है, लेकिन अगर फ़ोल्डर में किसी अन्य स्पार्क / हडोप जॉब से अतिरिक्त भाग फाइलें जैसे कुछ और हैं तो यह इन फाइलों को अधिलेखित नहीं करेगा।
सूअर का बच्चा

6
आप df.write.mode(mode: String).parquet(path)कहां मोड का उपयोग कर सकते हैं : स्ट्रिंग हो सकता है: "ओवरराइट", "एपेंड", "अनदेखा", "त्रुटि"।
रई

1
@ याओकाडो यूप ऐसा लगता है, स्पार्क एपीआई हर रिलीज पर खराब और बदतर हो जाता है: पी
समथबाइब

41

चूंकि 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" | "parquet" | "json")


1
sourceभी हो सकता हैcsv
रोमन


27

पैरामीटर के लिए दस्तावेज़ीकरण 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 => { } }

आस ने यहां बताया: http://apache-spark-user-list.1001560.n3.nabble.com/How-can-I-make-Spark-1-0-saveAsTextFile-to-overwrite-existing-file-td6696। एचटीएमएल


29
Pyspark के बारे में क्या?
जावदबा

'लिखने के लिए अगला जवाब। लिखने का तरीका (SaveMode.Overwrite)' जाने का रास्ता है
YaOg

एचडीएफ नई फाइलें हटा सकते हैं क्योंकि वे आते हैं क्योंकि यह अभी भी पुराने को हटा रहा है।
जेक

25

से pyspark.sql.DataFrame.save प्रलेखन (वर्तमान में 1.3.1 पर), आप निर्दिष्ट कर सकते हैं mode='overwrite'जब एक DataFrame की बचत:

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

मैंने सत्यापित किया है कि यह विभाजन फ़ाइलों पर छोड़ दिया जाएगा। इसलिए यदि आपने मूल रूप से 10 विभाजन / फाइलें कही थीं, लेकिन फिर उस फ़ोल्डर को एक डाटाफ्रेम से हटा दें जिसमें केवल 6 विभाजन थे, जिसके परिणामस्वरूप फ़ोल्डर में 6 विभाजन / फाइलें होंगी।

मोड विकल्पों के बारे में अधिक जानकारी के लिए स्पार्क SQL प्रलेखन देखें ।


2
सही और उपयोगी, धन्यवाद, लेकिन एक DataFrame विशिष्ट समाधान - spark.hadoop.validateOutputSpecsसभी स्पार्क एपीआई पर काम करेगा।
samthebest

किसी कारण से, spark.hadoop.validateOutputSpecsमेरे लिए 1.3 पर काम नहीं किया, लेकिन यह करता है।
एरिक वॉकर

1
@samthebest save(... , mode=मार्ग के साथ , आप एक ही स्पार्क संदर्भ में फ़ाइलों के एक सेट को अधिलेखित कर सकते हैं, दूसरे को जोड़ सकते हैं, आदि। spark.hadoop.validateOutputSpecsआप संदर्भ के लिए सिर्फ एक मोड के लिए सीमित नहीं होगा ?
dnlbrky

1
@dnlbrky ओपी को जोड़ने के लिए नहीं कहा। जैसा कि मैंने कहा, सच, उपयोगी, लेकिन अनावश्यक। यदि ओपी ने पूछा "मैं कैसे अपील करूं" तो जवाबों की एक पूरी श्रृंखला दी जा सकती है। लेकिन चलो उस में नहीं जाते हैं। इसके अलावा, मैं आपको सलाह देता हूं कि डेटाफ्रैम के स्काला संस्करण का उपयोग करने पर विचार करें क्योंकि इसमें टाइप सुरक्षा और अधिक जाँच है - उदाहरण के लिए यदि आपके पास "ओवरराइट" में एक टाइपो था, तो आपको यह पता नहीं चलेगा कि जब तक डीएजी का मूल्यांकन नहीं किया गया था - जो एक बिग डेटा नौकरी में हो सकता है 2 घंटे बाद !! यदि आप स्काला संस्करण का उपयोग करते हैं तो संकलक सब कुछ सामने की जाँच करेगा! बहुत अच्छा है, और बिग डेटा के लिए बहुत महत्वपूर्ण है।
samthebest

15

df.write.mode('overwrite').parquet("/output/folder/path")काम करता है अगर आप अजगर का उपयोग कर एक लकड़ी की छत फ़ाइल को अधिलेखित करना चाहते हैं। यह स्पार्क 1.6.2 में है। बाद के संस्करणों में API भिन्न हो सकता है


हां, यह मेरी आवश्यकता (डेटाब्रिक्स) के लिए बहुत अच्छा काम करता है
निक। एमसीडर्मिन

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)

केवल स्पार्क 1 के लिए, नवीनतम संस्करण उपयोग मेंdf.write.mode(SaveMode.Overwrite)
चिकूमीकु

3

मेरे लिए फ़ंक्शन सहेजने का यह अतिभारित संस्करण कार्य करता है:

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 ):

संलग्न : संलग्न मोड साधन जब कोई डेटा स्रोत के लिए एक DataFrame बचत, अगर डेटा / तालिका पहले से मौजूद है, DataFrame की सामग्री को मौजूदा डेटा के साथ जोड़ दिया हो जाने की उम्मीद कर रहे हैं।

ErrorIfExists : ErrorIfExists मोड का अर्थ है कि डेटा स्रोत में डेटाफ़्रेम को सहेजते समय, यदि डेटा पहले से मौजूद है, तो अपवाद को फेंक दिए जाने की उम्मीद है।

इग्नोर करें : इग्नोर मोड का मतलब है कि डेटा स्रोत में डेटाफ़्रेम को सहेजते समय, यदि डेटा पहले से मौजूद है, तो सेव ऑपरेशन से डेटाफ़्रेम की सामग्री को सहेजने और मौजूदा डेटा को नहीं बदलने की उम्मीद है।


1

यदि आप अपने स्वयं के कस्टम आउटपुट प्रारूप का उपयोग करने के इच्छुक हैं, तो आप आरडीडी के साथ वांछित व्यवहार प्राप्त करने में सक्षम होंगे।

निम्नलिखित कक्षाओं पर एक नज़र डालें: FileOutputFormat , FileOutputCommitter

फ़ाइल आउटपुट स्वरूप में आपके पास checkOutputSpecs नाम का एक तरीका है, जो यह जाँच रहा है कि आउटपुट निर्देशिका मौजूद है या नहीं। FileOutputCommitter में आपके पास कमिटमेंट है जो आमतौर पर अस्थायी निर्देशिका से डेटा को उसके अंतिम स्थान पर स्थानांतरित कर रहा है।

मैं अभी तक इसे सत्यापित नहीं कर पाया था (इसे करूंगा, जैसे ही मेरे पास कुछ मुफ्त मिनट होंगे) लेकिन सैद्धांतिक रूप से: यदि मैं FileOutputFormat का विस्तार करता हूं और checkOutputSpecs को एक विधि से ओवरराइड करता हूं, जो पहले से मौजूद निर्देशिका पर अपवाद नहीं फेंकता है, और समायोजित करें मेरे कस्टम आउटपुट की कमिटमेंट विधि, जो कभी भी मेरे द्वारा किए जाने वाले तर्क को निष्पादित करने के लिए कम करती है (जैसे कि कुछ फ़ाइलों को ओवरराइड करना, दूसरों को जोड़ना) की तुलना में मैं RDDs के साथ वांछित व्यवहार को प्राप्त करने में सक्षम हो सकता हूं।

आउटपुट स्वरूप को पास कर दिया गया है: saveAsNewAPIHadoopFile (जो विधि saveAsTextFile है जिसे वास्तव में फ़ाइलों को सहेजने के लिए कहा जाता है)। और आउटपुट कमिटर को एप्लिकेशन स्तर पर कॉन्फ़िगर किया गया है।


यदि आप इसकी मदद कर सकते हैं, तो मैं फाइलओटप्यूटकॉम्फ़िटर को उप-वर्ग के पास जाने से बचूँगा: यह एक डरावना सा कोड है। Hadoop 3.0 एक प्लगइन पॉइंट जोड़ता है जहाँ FileOutputFormat एक रिफलेक्टेड सुपरक्लास (PathOutputCommitter) के विभिन्न कार्यान्वयन ले सकता है। नेटफ्लिक्स का S3 एक विभाजन वाले पेड़ में जगह-जगह लिखेगा, केवल नौकरी के लिए संघर्ष समाधान (असफल, हटाएं, जोड़ें) कर रहा है, और केवल अद्यतन विभाजन में
stevel
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.