Pyspark dfからPostgresSQLに5,000万以上を書き込む、最も効率的なアプローチ


16

数百万のレコードを挿入する最も効率的な方法は、SparkデータフレームからPostgresテーブルに5,000万を挿入することです。私もこれまで成功したバルクコピーとバッチサイズオプションを利用して、これをSparkから 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を超えると、プロセスが速くなりますか?

千万レコードの平均14分悪くないですが、ヘルプにこの質問に答える前にこれをやっているだろうそこに人を探しています。


1
最初にデータをローカルCSVファイルにダンプし、次にPostgreSQL独自のインポートツールを使用してインポートすることができます。それはボトルネックの場所によって異なります。Pysparkからのエクスポートが遅いか、Postgresへのインポートが遅いか、または他の何かですか?(とはいえ、5,000万行で14分は、私にとってそれほど悪くはありません。テーブルで定義されているインデックスは何ですか?)

大、私は52milのdfを持っています、そして今それをPostgresに書いています、それは私が上記のコードを通して作成している新しいテーブルです。Postgresでテーブルを作成していないので、そこに書き込みません。最初にテーブルを作成し、そこにPostgresでインデックスを付けてから、spark dfからデータを送信できる場合、より良い可能性はありますか?
Chetan_Vasudevan

2
(それは逆です-インデックスはテーブルの挿入操作を遅くしますが、選択クエリを高速化します)
Dai

ダイ、それで私はインデックスなしでPostgresでテーブルを作成し、それから自分のパフォーマンスを挿入して測定してみますか?
Chetan_Vasudevan

2
stackoverflow.com/questions/758945/…役立つかもしれません。
Alexey Romanov

回答:


4

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

この質問に答えるためには、SparkとPostgresSQLの間の通信、特にSparkからPostgreSqlに流れるデータを最適化する必要があると思います。

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

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

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

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


Dbustosp私は間違いなく上記のヒントを試しますが、それまでは確かに賛成票を投じる価値があります。
Chetan_Vasudevan

@chetan_vasudevan使用しているデータ、レコードあたりのサイズなどの詳細を提供する場合。データが公開されている場合は、自分で何かを試して時間を比較できます。
dbustosp

Dbustospデータには80列とその5500万レコードがあります。あなたの提案に取り組み始めました。
Chetan_Vasudevan

@Chetan_Vasudevanデータセットの合計サイズ?入力データの形式は何ですか?
dbustosp

@Chetan_Vasudevan更新はありますか?
dbustosp
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.