web-dev-qa-db-fra.com

le parquet en étincelle écrit devient lent à mesure que les cloisons se développent

J'ai une application de streaming d'étincelles qui écrit des données de parquet à partir d'un flux.

sqlContext.sql(
      """
        |select
        |to_date(from_utc_timestamp(from_unixtime(at), 'US/Pacific')) as event_date,
        |hour(from_utc_timestamp(from_unixtime(at), 'US/Pacific')) as event_hour,
        |*
        |from events
        | where at >= 1473667200
      """.stripMargin).coalesce(1).write.mode(SaveMode.Append).partitionBy("event_date", "event_hour","verb").parquet(Config.eventsS3Path)

ce code fonctionne toutes les heures, mais avec le temps, l'écriture sur parquet s'est ralentie. Quand nous avons commencé, il fallait 15 minutes pour écrire des données, maintenant il faut 40 minutes. Il faut du temps en fonction des données existantes dans cette voie. J'ai essayé d'exécuter la même application sur un nouvel emplacement et cela fonctionne rapidement.

J'ai désactivé les métadonnées schemaMerge et récapitulatives:

sparkConf.set("spark.sql.Hive.convertMetastoreParquet.mergeSchema","false")
sparkConf.set("parquet.enable.summary-metadata","false")

utilisant spark 2.0

exécution par lots: répertoire vide  enter image description here  enter image description here  enter image description here répertoire avec 350 dossiers  enter image description here  enter image description here  enter image description here

12
Gaurav Shah

J'ai rencontré ce problème. Le mode append est probablement le coupable, dans la mesure où trouver l'emplacement de l'ajout prend de plus en plus de temps à mesure que la taille de votre fichier de parquet augmente. 

Une solution de contournement que j'ai trouvée qui résout ce problème consiste à modifier régulièrement le chemin de sortie. La fusion et la réorganisation des données de toutes les trames de données en sortie ne sont donc généralement pas un problème.

def appendix: String = ((time.milliseconds - timeOrigin) / (3600 * 1000)).toString

df.write.mode(SaveMode.Append).format("parquet").save(s"${outputPath}-H$appendix")
1
huitseeker

Essayez d'écrire le dataframe sur EMR HDFS (hdfs: // ...), puis utilisez s3-dist-cp pour télécharger les données de HDFS vers S3. Travaillé pour moi.

0
Niros

Cela peut être dû au mode Ajout. Dans ce mode, les nouveaux fichiers doivent être générés avec des noms différents des fichiers existants. Par conséquent, spark liste les fichiers dans s3 (ce qui est lent) à chaque fois.

Nous avons également défini parquet.enable.summary-metadata un peu différemment:

javaSparkContext.hadoopConfiguration().set("parquet.enable.summary-metadata", "false");
0
Igor Berman