2016-10-13 5 views
2

私はプロトタイプ作成中の推奨エンジンのSpark操作のパフォーマンスを向上させるために取り組んでいます。私は使用しているDataFramesとの間に大きなパフォーマンスの違いを見つけました。両方の上の記述()の結果の下に。非常によく似た2つのSpark Dataframesのパフォーマンスの違いの原因

DF1(速い、numPartitions = 4):

+-------+------------------+--------------------+ 
|summary|   item_id|   popularity| 
+-------+------------------+--------------------+ 
| count|   187824|    187824| 
| mean| 96693.34836868558|     1.0| 
| stddev|55558.023793621316|5.281958866780519...| 
| min|     0| 0.9999999999999998| 
| max|   192806|     1.0| 
+-------+------------------+--------------------+ 

DF2(遅い約10倍、numPartitions =±170):

+-------+-----------------+-----------------+ 
|summary|   item_id|   count| 
+-------+-----------------+-----------------+ 
| count|   187824|   187824| 
| mean|96693.34836868558|28.70869537439305| 
| stddev|55558.02379362146|21.21976457710462| 
| min|    0|    1| 
| max|   192806|    482| 
+-------+-----------------+-----------------+ 

両方のデータフレームは、点で同じサイズをキャッシュされます列(187824)と列(2)の列であり、同じitem_id列を持ちます。主な違いは、フレーム1には2番目の列にfloatが含まれ、フレーム2には整数が含まれている点です。

DataFrame 2のすべての操作が、単に.describe().show()の操作から、さらに詳細な.subtract().subtract().take()に至るまではるかに遅いようです。後者の場合、DataFrame 2はフレーム1の場合は2秒(約10倍遅くなります)ではなく、18秒かかります。

この違いの原因の説明をどこから始めるべきかわかりません。正しい方向のヒントやナッジがあれば大歓迎です。

UPDATE:Viacheslav Rodionovが提案したように、データフレームのパーティション数がdf2のパフォーマンス問題の原因になっているようです。

さらに深く掘り下げてみると、両方のデータフレームは同じ元のデータフレーム上で.groupBy().agg().sortBy()操作の結果です。 .groupBy().agg()の操作では200個のパーティションが生成され、.sortBy()はそれぞれ4個と170個のパーティションを返します。それは、データがよりよく圧縮することを可能にするとファイルの操作ではなく、より実際の作業を行うためとして

+1

私はdf.rddを見ることから始めます。getNumPartitions() –

+0

パーティション数は174(低速)と4(高速)です。このヒントをありがとう、私はこれについて何かを読んで覚えて、私は状況を理解するために深く掘るでしょう。 Sparkによってパーティションの数が自動的に選択されました。試行錯誤、手作業による唯一の調整方法ですか? – Fulco

答えて

3

私はdf.rdd.getNumPartitions()

を見てから始めましょう大きなパーティションの数が少ないが、ほとんど常に良い考えです。

もう1つは、データの見た目です。あなたがやろうとしている仕事には適切ですか?

  • BETWEEN操作を適用するために使用している日付フィールドで注文されている場合は、並べ替えられていないデータを処理するよりも速くなります。
  • 特定の月または年を使用して作業する場合、データをパーティション分割することは意味があります。
  • IDは同じです。特定のIDで作業する場合は、データセットを分割/ソートすることによって、同じIDを「近くに」配置します。

親指の私のルールデータを格納する - データの重要度順にsortWithinPartitionsと、その後、いくつかの低カーディナリティのフィールドによって、最初のパーティション(ブール値とほとんど日付)、ソートすべて他のフィールド。この方法で、最高の圧縮率(処理時間が速くなる)とデータのローカリティが向上します(処理時間が短縮されます)。しかし、常にそれはすべてあなたのユースケースに依存しているので、あなたがデータをどのように扱っているかを常に考えて、それに応じて準備してください。

+0

あなたの答えをありがとう。実際には、両方のデータフレームが2番目の列(それぞれカウントと人気度)でソートされます。また、両方のフレームは、同じ元のデータフレームからの '.groupBy()。agg()。sortBy()'演算の結果です。 'groupBy.agg()'のステップは、両方の場合に200のパーティションを生成するように見えますが、 'sortBy'はそれぞれ4と170を生成します。これがなぜ起こっているのかを今解明しようとしたら – Fulco

+0

df2から4へのパーティション分割がパフォーマンスを大幅に向上させることが確認できました。 – Fulco

+0

@Fulco 'groupBy'はあなたのデータをローカルで最初にグループ化します。 'groupBy()。agg()'の前後でgetNumPartitionsをチェックしてください。それは同じですか?次に、ソートするときには、まずローカルにプリソートしてから、すべてのデータを1つの場所に転送します。データをソートし、パーティション内で事前ソートしたフィールドでパーティション化したとすると、あまり転送する必要はありません。 –

関連する問題