何百万ものレコードを挿入する最も効率的な方法は、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分は悪くありませんが、この質問に答えるために以前にこれを行っていたであろう人々を探します。
私は少し前に同じような作業を実際に行いましたが、Apache Sqoopを使用しました。
この質問に答えるためには、SparkとPostgresSQLの間の通信、特にSparkからPostgreSqlに流れるデータが必要です。
ただし、注意してくださいSpark side。パーティションの数がmapPartitionsの場合、実行しても意味がありませんPostgreSQLがサポートする最大接続数と比較して高すぎます。パーティションが多すぎて、それぞれの接続を開いている場合、おそらく次のエラーorg.postgresql.util.PSQLException: FATAL: sorry, too many clients already
。
挿入プロセスを調整するために、次の手順に従って問題に取り組みます。
coalesce
を確認することをお勧めします here 。最後に、この仕事をするための特効薬はありません。上記のすべてのヒントを使用できますが、それは実際にはデータとユースケースに依存します。