web-dev-qa-db-fra.com

Écrire plus de 50 millions de Pyspark df à PostgresQL, la meilleure approche efficace

Quelle serait la façon la plus efficace d'insérer des millions d'enregistrements, par exemple 50 millions à partir d'un Spark dataframe to Postgres Tables. Je l'ai fait de spark to - MSSQL dans le passé en utilisant la copie en bloc et la taille du lot option qui a également réussi.

Y a-t-il quelque chose de similaire qui peut être ici pour Postgres?

Ajout du code que j'ai essayé et du temps qu'il a fallu pour exécuter le processus:

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

J'ai donc fait l'approche ci-dessus pour 10 millions d'enregistrements et avait 5 connexions parallèles comme spécifié dans numPartitions et j'ai également essayé une taille de lot de 200k.

Le temps total qu'il a fallu pour le processus était : 14: 05.760926 (quatorze minutes et cinq secondes).

Existe-t-il une autre approche efficace qui réduirait le temps?

Quelle serait la taille de lot efficace ou optimale que je peux utiliser? L'augmentation de la taille de mon lot fera-t-elle le travail plus rapidement? Ou ouvrir plusieurs connexions, c'est-à-dire> 5, m'aider à accélérer le processus?

Sur un 14 minutes en moyenne pour 10 millions d'enregistrements n'est pas mauvais, mais à la recherche de personnes qui auraient fait cela auparavant pour aider à répondre à cette question.

16
Chetan_Vasudevan

En fait, j'ai fait un peu le même travail il y a quelque temps, mais en utilisant Apache Sqoop.

Je dirais que pour répondre à ces questions, nous devons essayer d'optimiser la communication entre Spark et PostgresSQL, en particulier les données provenant de Spark vers PostgreSql.

Mais attention, n'oubliez pas Spark side. Cela n'a pas de sens d'exécuter mapPartitions si le nombre de partitions est trop élevé par rapport au nombre de connexions maximum prises en charge par PostgreSQL, si vous avez trop de partitions et que vous ouvrez une connexion pour chacune, vous aurez probablement l'erreur suivante org.postgresql.util.PSQLException: FATAL: sorry, too many clients already.

Afin de régler le processus d'insertion, j'aborderais le problème en suivant les étapes suivantes:

  • N'oubliez pas que le nombre de partitions est important. Vérifiez le nombre de partitions, puis ajustez-le en fonction du nombre de connexions parallèles que vous souhaitez avoir. Vous voudrez peut-être avoir une connexion par partition, je suggère donc de vérifier coalesce, comme mentionné ici .
  • Vérifiez le nombre maximum de connexions prises en charge par votre instance postgreSQL et que vous souhaitez augmenter le nombre .
  • Pour insérer des données dans PostgreSQL est recommandé en utilisant la commande COPY . Ici est également une réponse plus élaborée sur la façon d'accélérer l'insertion postgreSQL.

Enfin, il n'y a pas de solution miracle pour faire ce travail. Vous pouvez utiliser tous les conseils que j'ai mentionnés ci-dessus, mais cela dépendra vraiment de vos données et de vos cas d'utilisation.

4
dbustosp