web-dev-qa-db-ja.com

スピードアップ方法spark DF.Write JDBCへPostgresデータベースに?

sparkには、DF.Writeを使用してPostgresデータベースにデータフレームの内容(200kから2Mの行の間で持つことができます)の内容を追加しようとしています。

_df.write.format('jdbc').options(
      url=psql_url_spark,
      driver=spark_env['PSQL_DRIVER'],
      dbtable="{schema}.{table}".format(schema=schema, table=table),
      user=spark_env['PSQL_USER'],
      password=spark_env['PSQL_PASS'],
      batchsize=2000000,
      queryTimeout=690
      ).mode(mode).save()
_

私はバッチサイズを増やしてみましたが、このタスクを完了すると、〜4時間かかったとして、助けはありませんでした。また、AWS EMRから以下にスナップショットを含めました。 DataFrameをPostgresテーブルに保存するタスクは、1つのエグゼキュータ(奇妙に見つけた)にのみ割り当てられていましたが、これをスピードアップすると、このタスクをエグゼクティブ間で分割することがあります。

また、読み取り Sparkのパフォーマンス調整ドキュメントbatchsizequeryTimeoutを増やすと、パフォーマンスを向上させていません。 (_df.write_の前に、スクリプトでdf.cache()を呼び出してみましたが、スクリプトの実行時はまだ4時間でした)

さらに、私のAWS EMRハードウェア設定と_spark-submit_は次のとおりです。

マスターNode(1):m4.xlarge

コアノード(2):M5.xlarge.

_spark-submit --deploy-mode client --executor-cores 4 --num-executors 4 ...
_

enter image description here

enter image description here

10
Megan

データフレームを再分割することによって、より良い書き込みパフォーマンスは既知の答えであることを達成することができます。しかし、データフレームを再分割するための最適な方法があります。このプロセスをEMRクラスタで実行しているので、最初にインスタンスタイプと各スレーブインスタンスで実行されているコアの数について知ります。それによると、データフレーム上のパーティションの数を指定します。あなたの場合では、インスタンスごとに4つのスレッドを意味する4 Vcpusを持つM5.xlarge(2スレーブ)を使用しています。それで、あなたが巨大なデータを扱っているときに8つのパーティションはあなたに最適な結果を与えます。

注:データサイズに基づいてパーティションの数を増減する必要があります。

注:バッチサイズもあなたの書き込みで考慮すべきものです。バッチサイズを大きくすると、パフォーマンスが向上しました