I/O が少ない低速の Spark ステージ

I/O があまりない低速ステージの場合は、次の原因が考えられます。

  • 小さなファイルを大量に読み込む

  • 小さなファイルを大量に書き込む

  • 遅いUDF

  • デカルト結合

  • 結合の展開

これらの問題のほとんどは、SQL DAG を使用して特定できます。

SQL DAGを開く

SQL DAG を開くには、ジョブのページの上部までスクロールし、関連付けられた SQL クエリをクリックします。

SQL

これで DAG が表示されます。 そうでない場合は、少しスクロールすると表示されます。

SLQダグ

先に進む前に、DAG と、どこで時間が費やされているかをよく理解してください。 DAG 内の一部のノードには役立つ時間情報がありますが、他のノードにはそれがありません。 たとえば、このブロックは 2.1 分かかり、ステージ ID も提供します。

Slow Stage(スローステージ)ノード

このノードを開くと、1.4分かかったことがわかります。

低速書き込みノード

これらの時間は累積されるため、すべてのタスクに費やされた合計時間であり、時計の時間ではありません。 しかし、クロック時間とコストと相関しているため、それでも非常に便利です。

DAG のどこで時間が費やされているかをよく理解しておくと役に立ちます。

小さなファイルを大量に読み込む

スキャンオペレーターの1つに多くの時間がかかっていることがわかった場合は、それを開いて、読み取られたファイルの数を探します。

多数のファイルの読み取り

数万個以上のファイルを読み取っている場合は、小さなファイルの問題が発生している可能性があります。 ファイルは8MB以上である必要があります。 ファイルサイズが小さい問題は、ほとんどの場合、列が多すぎるか、カーディナリティの高い列でパーティション分割されることが原因です。

運が良ければ、 OPTIMIZE を実行するだけで済むかもしれません。 いずれにせよ、 ファイルのレイアウトを再検討する必要があります。

小さなファイルを大量に書き込む

書き込みに時間がかかる場合は、書き込みを開いて、ファイルの数と書き込まれたデータの量を探します。

多数のファイルを書き込む

数万個以上のファイルを書き込んでいる場合は、小さなファイルの問題が発生している可能性があります。 ファイルは8MB以上である必要があります。 ファイルサイズが小さい問題は、ほとんどの場合、列が多すぎるか、カーディナリティの高い列でパーティション分割されることが原因です。 ファイルのレイアウトを見直すか、最適化された書き込みをオンにする必要があります。

低速な UDF

UDF があることがわかっている場合、または DAG にこのようなものが表示される場合は、UDF の速度が低下している可能性があります。

UDFノード

この問題が発生していると思われる場合は、UDF をコメント アウトして、パイプラインの速度にどのような影響があるかを確認してください。 実際に UDF に時間がかかっている場合は、ネイティブ関数を使用して UDF を書き直すのが最善策です。 それが不可能な場合は、UDF を実行するステージ内のタスクの数を考慮してください。 クラスターのコア数より少ない場合は、UDF を使用する前にデータフレームをrepartition()ます。

  (df
    .repartition(num_cores)
    .withColumn('new_col', udf(...))
  )

UDF は、メモリの問題に悩まされる可能性もあります。 各タスクはパーティション内のすべてのデータをメモリにロードする必要がある場合があることを考慮してください。 このデータが大きすぎると、処理が非常に遅くなったり、不安定になったりする可能性があります。 再パーティション化により、各タスクを小さくすることでこの問題を解決することもできます。

デカルト結合

DAG にデカルト結合または入れ子ループ結合が表示される場合は、これらの結合が非常にコストがかかることを知っておく必要があります。 それが意図したものであることを確認し、別の方法があるかどうかを確認します。

分解結合または分解

ノードにいくつかの行が入り、さらに大きな行が出てくる場合は、結合またはexplode()の爆発に苦しんでいる可能性があります。

結合の展開

爆発の詳細については、Databricks 最適化ガイドを参照してください。