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
}
しかし、このようにeveryDataFrame
のrdd.getNumPartitions
のコストを負担する余裕はありません。
この情報を取得する方法はありませんか。多分catalog
テーブルのためにオンライン/一時的なregistered
をクエリすることから?
UpdateSpark GUIは、DataFrame.rdd操作がジョブ内の最長のSQLと同じくらい長くかかることを示しました。ジョブを再実行し、スクリーンショットをここに添付します。
以下は単なるtestcaseです。本番環境ではデータサイズのごく一部を使用しています。最長のsql
はわずか5分です。これは、その時間を費やす途中です同様に(sql
はであることに注意してください) notここで助けられました:それはその後も実行する必要があるため、累積実行時間を事実上2倍にします)。
DataFrameUtils
行30の.rdd
操作(上記のスニペットに表示)は5.1分かかりますが、save
操作stillがかかっていることがわかります5.2分後-すなわちnot後続のsave
の実行時間に関して.rdd
を実行することで、時間を節約しました。
私の経験ではdf.rdd.getNumPartitions
は非常に高速で、これを1秒以上かかることはありませんでした。
あるいは、あなたも試すことができます
val numPartitions: Long = df
.select(org.Apache.spark.sql.functions.spark_partition_id()).distinct().count()
.rdd
の使用を避けます