Scrivere più di 50 milioni da Pyspark df a PostgresSQL, il miglior approccio efficiente


16

Quale sarebbe il modo più efficiente per inserire milioni di record dire 50 milioni da un frame di dati Spark a Tabelle Postgres. In passato l' ho fatto da Spark a MSSQL facendo uso dell'opzione di copia bulk e dimensione batch che ha avuto successo.

C'è qualcosa di simile che può essere qui per Postgres?

Aggiunta del codice che ho provato e tempo impiegato per eseguire il processo:

def inserter():
    start = timer()
    sql_res.write.format("jdbc").option("numPartitions","5").option("batchsize","200000")\
    .option("url", "jdbc:postgresql://xyz.com:5435/abc_db") \
    .option("dbtable", "public.full_load").option("user", "root").option("password", "password").save()
    end = timer()
    print(timedelta(seconds=end-start))
inserter()

Quindi ho seguito l'approccio sopra descritto per 10 milioni di record e avevo 5 connessioni parallele come specificato in numPartitionse ho anche provato una dimensione batch di 200k .

Il tempo totale impiegato per il processo è stato 0: 14: 05.760926 (quattordici minuti e cinque secondi).

Esiste un altro approccio efficace che riduca i tempi?

Quale sarebbe la dimensione del lotto efficiente o ottimale che posso usare? Aumentando la dimensione del mio lotto il lavoro sarà più veloce? O l'apertura di più connessioni, ovvero> 5, mi aiuta a rendere il processo più veloce?

In media 14 minuti per 10 milioni di dischi non è male , ma cercare persone là fuori che lo avrebbero fatto prima per aiutare a rispondere a questa domanda.


1
Potresti prima scaricare i dati in un file CSV locale, quindi utilizzare gli strumenti di importazione di PostgreSQL per importarli - dipende da dove si trova il collo di bottiglia: è lento esportare da Pyspark o lento importare in Postgres o qualcos'altro? (Detto questo, 14 minuti per 50 milioni di righe non mi sembrano così male - quali indici sono definiti nella tabella?).
Dai

Dai, ho un df che è 52mil e ora lo scrivo su Postgres, è una nuova tabella che sto creando attraverso il codice sopra. Non ho creato la tabella in Postgres e poi scrivendo lì. Esiste una possibilità migliore se posso prima creare una tabella e indicizzarla lì in Postgres e quindi inviare i dati da spark df?
Chetan_Vasudevan,

2
(È il contrario: gli indici rallentano le operazioni di inserimento sulle tabelle, ma accelerano le query selezionate)
Dai

Dai, quindi creo la tabella in Postgres senza indice e quindi provo a inserire e misurare le mie prestazioni?
Chetan_Vasudevan,

Risposte:


4

In realtà ho fatto lo stesso lavoro qualche tempo fa ma usando Apache Sqoop.

Direi che per rispondere a queste domande dobbiamo cercare di ottimizzare la comunicazione tra Spark e PostgresSQL, in particolare i dati che fluiscono da Spark a PostgreSql.

Ma fai attenzione, non dimenticare il lato Spark. Non ha senso eseguire mapPartitions se il numero di partizioni è troppo elevato rispetto al numero di connessioni massime supportate da PostgreSQL, se hai troppe partizioni e stai aprendo una connessione per ognuna, probabilmente avrai il seguente errore org.postgresql.util.PSQLException: FATAL: sorry, too many clients already.

Per ottimizzare il processo di inserimento, vorrei affrontare il problema seguendo i passaggi seguenti:

  • Ricorda che il numero di partizioni è importante. Controllare il numero di partizioni e quindi regolarlo in base al numero di connessione parallela che si desidera avere. Potresti voler avere una connessione per partizione, quindi suggerirei di controllare coalesce, come è menzionato qui .
  • Controlla il numero massimo di connessioni supportate dall'istanza postgreSQL e desideri aumentare il numero .
  • Per l'inserimento di dati in PostgreSQL si consiglia di utilizzare il comando COPIA . Ecco anche una risposta più elaborata su come velocizzare l'inserimento di postgreSQL.

Infine, non esiste un proiettile d'argento per fare questo lavoro. Puoi usare tutti i suggerimenti che ho menzionato sopra, ma dipenderà davvero dai tuoi dati e dai casi d'uso.


Dbustosp Proverò sicuramente i suggerimenti di cui sopra, fino ad allora meriterai sicuramente un voto.
Chetan_Vasudevan,

@chetan_vasudevan se fornisci maggiori dettagli sui dati che stai utilizzando, dimensione per record, ecc. Se i dati sono pubblici posso provare qualcosa da solo e confrontare i tempi.
dbustosp,

Dbustosp i dati hanno 80 colonne e i suoi 55 milioni di record. Ho iniziato a lavorare sui suggerimenti che mi hai dato.
Chetan_Vasudevan,

@Chetan_Vasudevan La dimensione totale del set di dati? Qual è il formato dei dati di input?
dbustosp,

@Chetan_Vasudevan Qualche aggiornamento?
dbustosp,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.