2015-09-29 2 views
10

ho una struttura di directory basata su due partizioni, in questo modo:risparmio al parquet sottopartizione

People 
    > surname=Doe 
     > name=John 
     > name=Joe 
    > surname=White 
     > name=Josh 
     > name=Julien 

sto leggendo i file in parquet con le informazioni solo circa tutto fa, e dunque sono direttamente specificando cognome = Doe come directory di output per il mio DataFrame. Ora il problema è che sto cercando di aggiungere il partizionamento basato sul nome con partitionBy("name") sulla scrittura.

df.write.partitionBy("name").parquet(outputDir) 

(OutputDir contiene un percorso a directory Doe)

Questo causa un errore come di seguito:

Caused by: java.lang.AssertionError: assertion failed: Conflicting partition column names detected: 
    Partition column name list #0: surname, name 
    Partition column name list #1: surname 

Eventuali suggerimenti come risolverlo? Probabilmente si verifica a causa del file _SUCCESS creato nella directory del cognome, che fornisce suggerimenti errati a Spark - quando rimuovo i file _SUCCESS e _metadata Spark è in grado di leggere tutto senza problemi.

risposta

7

sono riuscito a risolvere con una soluzione - non credo che questa sia una buona idea, ma ho disattivato la creazione _SUCCESS aggiuntivo e file _metadata con:

sc.hadoopConfiguration.set("mapreduce.fileoutputcommitter.marksuccessfuljobs", "false") 
sc.hadoopConfiguration.set("parquet.enable.summary-metadata", "false") 

In questo modo non sarà possibile ottenere Spark qualsiasi idea stupida sulle strutture di partizionamento.

Un'altra opzione è il risparmio per i "propri" Directory - Persone e partizione per cognome e nome, ma poi si deve tenere a mente che l'unica opzione sensata sta mettendo SaveMode-Append ed eliminando manualmente le directory che ci si aspetta di essere sovrascritto (questo è davvero soggetto a errori):

df.write.mode(SaveMode.Append).partitionBy("surname","name").parquet("/People") 

non utilizzare SaveMode owerwrite in questo caso - questo sarà eliminare tutti i directores cognome.

+0

Poiché nessun altro ha scritto e la mia generosità scade , Accetto questa soluzione come l'unica conosciuta per ora. – Niemand

+0

Questo ha funzionato per me per Spark 1.6.3 'sc._jsc.hadoopConfiguration(). Set (" mapreduce.fileoutputcommitter.marksuccessfuljobs "," false ") sc._jsc.hadoopConfiguration(). Set (" parquet.enable.summary -metadata "," false ")' – Vezir

2
sc.hadoopConfiguration.set("parquet.enable.summary-metadata", "false") 

è abbastanza sensibile, se si dispone di metadati sintesi abilitata, la scrittura del file di metadati può diventare un collo di bottiglia IO sulla legge e scrive.

Il modo alternativo per la soluzione potrebbe essere quella di aggiungere un .mode ("aggiungere") per il vostro articolo, ma con la directory padre originale come destinazione,

df.write.mode("append").partitionBy("name").parquet("/People") 
+0

Il problema con append è che dovrei cancellare manualmente i dati, il che sarebbe fastidioso nel mio caso. – Niemand

+0

Vero, ma l'eliminazione delle partizioni dei file in Spark è comunque al massimo rudimentale ... –