web-dev-qa-db-ja.com

Pyspark dfからPostgresQLへの5,000万以上の書き込み、最高の効率的なアプローチ

何百万ものレコードを挿入する最も効率的な方法は、Spark dataframe to Postgres Tables to 5000million。と言います。私はこれをspark to過去のMSSQLの一括コピーとバッチサイズオプションを使用して、成功しました。

Postgresのためにここにあることができる同様のものはありますか?

私が試したコードとプロセスの実行にかかった時間を追加します:

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

したがって、1000万件のレコードに対して上記のアプローチを実行し、numPartitionsで指定されているように5つの並列接続を実行し、200kのバッチサイズも試しました。

プロセスにかかった合計時間は0:14:05.760926(14分5秒)でした。

時間を短縮する他の効率的なアプローチはありますか?

私が使用できる効率的または最適なバッチサイズは何ですか?バッチサイズを大きくすると、作業が速くなりますか?または、複数の接続を開く(つまり、5以上)と、プロセスが速くなりますか?

1,000万レコードの平均14分は悪くありませんが、この質問に答えるために以前にこれを行っていたであろう人々を探します。

16

私は少し前に同じような作業を実際に行いましたが、Apache Sqoopを使用しました。

この質問に答えるためには、SparkとPostgresSQLの間の通信、特にSparkからPostgreSqlに流れるデータが必要です。

ただし、注意してくださいSpark side。パーティションの数がmapPartitionsの場合、実行しても意味がありませんPostgreSQLがサポートする最大接続数と比較して高すぎます。パーティションが多すぎて、それぞれの接続を開いている場合、おそらく次のエラーorg.postgresql.util.PSQLException: FATAL: sorry, too many clients already

挿入プロセスを調整するために、次の手順に従って問題に取り組みます。

  • パーティションの数が重要であることを忘れないでください。パーティションの数を確認し、必要な並列接続の数に基づいて調整します。パーティションごとに1つの接続が必要になる場合があるので、言及されているように、coalesceを確認することをお勧めします here
  • PostgreSQLインスタンスがサポートしていて 数を増やす にする接続の最大数を確認します。
  • PostgreSQLにデータを挿入する場合 COPYコマンドを使用することをお勧めしますここ は、postgreSQLの挿入を高速化する方法についての詳細な回答でもあります。

最後に、この仕事をするための特効薬はありません。上記のすべてのヒントを使用できますが、それは実際にはデータとユースケースに依存します。

4
dbustosp