web-dev-qa-db-ja.com

.rddのコストを発生させずに、Spark DataFrameのパーティション数を確認する方法

N RDDおよびまたはDataFrameのパーティション数を取得する方法については、いくつかの質問があります。答えは常に次のとおりです。

 rdd.getNumPartitions

または

 df.rdd.getNumPartitions

残念ながら、これはDataFrameに対する高価操作です。

 df.rdd

DataFrameからrddへの変換が必要です。これは実行にかかる時間のオーダーです

 df.count

オプションrepartition 'sまたはcoalesce' s a DataFrame-currentパーティションの数が許容値の範囲内、またはその下または上。

  def repartition(inDf: DataFrame, minPartitions: Option[Int],
       maxPartitions: Option[Int]): DataFrame = {
    val inputPartitions= inDf.rdd.getNumPartitions  // EXPENSIVE!
    val outDf = minPartitions.flatMap{ minp =>
      if (inputPartitions < minp) {
        info(s"Repartition the input from $inputPartitions to $minp partitions..")
        Option(inDf.repartition(minp))
      } else {
        None
      }
    }.getOrElse( maxPartitions.map{ maxp =>
      if (inputPartitions > maxp) {
        info(s"Coalesce the input from $inputPartitions to $maxp partitions..")
        inDf.coalesce(maxp)
      } else inDf
    }.getOrElse(inDf))
    outDf
  }

しかし、このようにeveryDataFramerdd.getNumPartitionsのコストを負担する余裕はありません。

この情報を取得する方法はありませんか。多分catalogテーブルのためにオンライン/一時的なregisteredをクエリすることから?

UpdateSpark GUIは、DataFrame.rdd操作がジョブ内の最長のSQLと同じくらい長くかかることを示しました。ジョブを再実行し、スクリーンショットをここに添付します。

以下は単なるtestcaseです。本番環境ではデータサイズのごく一部を使用しています。最長のsqlはわずか5分です。これは、その時間を費やす途中です同様にsqlであることに注意してください) notここで助けられました:それはその後も実行する必要があるため、累積実行時間を事実上2倍にします)。

enter image description here

DataFrameUtils行30の.rdd操作(上記のスニペットに表示)は5.1分かかりますが、save操作stillがかかっていることがわかります5.2分後-すなわちnot後続のsaveの実行時間に関して.rddを実行することで、時間を節約しました。

6
javadba

私の経験ではdf.rdd.getNumPartitionsは非常に高速で、これを1秒以上かかることはありませんでした。

あるいは、あなたも試すことができます

val numPartitions: Long = df
      .select(org.Apache.spark.sql.functions.spark_partition_id()).distinct().count()

.rddの使用を避けます

2
Raphael Roth