web-dev-qa-db-fra.com

Comment écraser le répertoire de sortie dans spark

J'ai une application de streaming spark qui produit un jeu de données pour chaque minute. J'ai besoin de sauvegarder/écraser les résultats des données traitées.

Lorsque j'ai essayé d'écraser l'ensemble de données org.Apache.hadoop.mapred.FileAlreadyExistsException, il arrête l'exécution.

J'ai défini la propriété Spark _ set("spark.files.overwrite","true"), mais il n'y a pas de chance.

Comment écraser ou pré-supprimer les fichiers de spark?

87
Vijay Innamuri

UPDATE: Suggérez d'utiliser Dataframes, plus quelque chose comme ... .write.mode(SaveMode.Overwrite) ....

Pour les anciennes versions, essayez

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

Dans la version 1.1.0, vous pouvez définir les paramètres de configuration à l'aide du script spark-submit avec l'indicateur --conf.

AVERTISSEMENT (anciennes versions): Selon @piggybox, il existe un bogue dans Spark qui écrase uniquement les fichiers dont il a besoin pour écrire ses fichiers part-. Tous les autres fichiers ne seront pas supprimés.

90
samthebest

La documentation relative au paramètre spark.files.overwrite indique ce qui suit: "Si les fichiers ajoutés via SparkContext.addFile() doivent être écrasés lorsque le fichier cible existe et que son contenu ne correspond pas à celui de la source." Elle n’a donc aucun effet sur la méthode saveAsTextFiles.

Vous pouvez le faire avant d’enregistrer le fichier:

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 a expliqué ici: http://Apache-spark-user-list.1001560.n3.nabble.com/How-can-I-make-Spark-1-0-saveAsTextFile-to-overwrite-existing- fichier-td6696.html

26
pzecevic

depuis df.save(path, source, mode) est obsolète, ( http://spark.Apache.org/docs/1.5.0/api/scala/index.html#org.Apache.spark.sql.DataFrame )

utiliser df.write.format(source).mode("overwrite").save(path)
où df.write est DataFrameWriter

'source' peut être ("com.databricks.spark.avro" | "parquet" | "json")

25
Curycu

Dans la documentation pyspark.sql.DataFrame.save (actuellement à la version 1.3.1), vous pouvez spécifier mode='overwrite' lors de l’enregistrement d’un DataFrame:

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

J'ai vérifié que cela supprimera même les fichiers de partition laissés. Donc, si vous aviez dit 10 partitions/fichiers à l'origine, mais que vous avez ensuite écrasé le dossier avec un DataFrame qui n'avait que 6 partitions, le dossier résultant contiendrait les 6 partitions/fichiers.

Reportez-vous à documentation Spark SQL pour plus d'informations sur les options de mode.

22
dnlbrky

df.write.mode ('écraser'). parquet ("/ output/folder/path") fonctionne si vous voulez écraser un fichier parquet en utilisant python. C'est dans spark 1.6.2. L'API peut être différent dans les versions ultérieures

6
akn
  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)
4
vaquar khan

Cette version surchargée de la fonction save fonctionne pour moi:

yourDF.save (outputPath, org.Apache.spark.sql.SaveMode.valueOf ("Ecraser"))

L'exemple ci-dessus écraserait un dossier existant. Le savemode peut également prendre ces paramètres ( https://spark.Apache.org/docs/1.4.0/api/Java/org/Apache/spark/sql/SaveMode.html ):

Append : le mode Append signifie que lors de l'enregistrement d'un DataFrame dans une source de données, si data/table existe déjà, le contenu du DataFrame devrait être ajouté à données existantes.

ErrorIfExists : le mode ErrorIfExists signifie que lors de l'enregistrement d'un DataFrame dans une source de données, si des données existent déjà, une exception doit être levée.

Ignore : le mode Ignore signifie que lors de la sauvegarde d'un DataFrame dans une source de données, si des données existent déjà, l'opération de sauvegarde ne devrait pas sauvegarder le contenu du fichier. DataFrame et ne pas modifier les données existantes.

2
Shay

Si vous souhaitez utiliser votre propre format de sortie personnalisé, vous pourrez également obtenir le comportement souhaité avec RDD.

Examinez les classes suivantes: FileOutputFormat , FileOutputCommitter

Dans le format de sortie du fichier, vous avez une méthode appelée checkOutputSpecs, qui vérifie si le répertoire de sortie existe. FileOutputCommitter contient le commitJob, qui transfère généralement les données du répertoire temporaire à son emplacement final.

Je ne pouvais pas encore le vérifier (le ferais dès que j'ai quelques minutes gratuites) mais théoriquement: Si j'étends FileOutputFormat et que je substitue checkOutputSpecs à une méthode qui ne lève pas d'exception sur le répertoire, ajuste le La méthode commitJob de mon créateur de sortie personnalisé exécute la logique que je souhaite (par exemple, remplacer certains des fichiers, en ajouter d’autres) que je ne serais peut-être en mesure d’obtenir le comportement souhaité avec les RDD.

Le format de sortie est transmis à: saveAsNewAPIHadoopFile (qui est la méthode saveAsTextFile également appelée pour enregistrer les fichiers). Et le déclencheur de sortie est configuré au niveau de l'application.

0
Michael Kopaniov