2つのDataFrameを効果的に結合しようとしています。1つは大きく、2つ目は少し小さくなっています。
このすべてのシャッフルを回避する方法はありますか? autoBroadCastJoinThreshold
を設定することはできません。整数のみをサポートしているためです。また、ブロードキャストしようとしているテーブルは、整数のバイト数よりも少し大きいです。
この変数を無視してブロードキャストを強制する方法はありますか?
SparkSQLでは、_queryExecution.executedPlan
_を呼び出すことにより、実行されている結合のタイプを確認できます。コアSparkと同様に、テーブルの1つが他のテーブルよりもはるかに小さい場合、ブロードキャストハッシュ結合が必要になる場合があります。 Spark SQLに、broadcast
でメソッドDataFrame
を呼び出すことで、指定されたDFを結合のためにブロードキャストするようにヒントを出すことができます。
例:largedataframe.join(broadcast(smalldataframe), "key")
dWH用語では、largedataframeはfact
smalldataframeはdimensionのようになります
私のお気に入りの本(HPS)plsで説明されているように。理解を深めるために、以下を参照してください。
注:上記のbroadcast
はSparkContext
からではなく_import org.Apache.spark.sql.functions.broadcast
_からのものです
また、Sparkは_spark.sql.conf.autoBroadcastJoinThreshold
_を自動的に使用して、テーブルをブロードキャストする必要があるかどうかを判断します。
_def
explain(): Unit
Prints the physical plan to the console for debugging purposes.
_
この変数を無視してブロードキャストを強制する方法はありますか?
sqlContext.sql("SET spark.sql.autoBroadcastJoinThreshold = -1")
注:
別の同様のすぐに使えるノートw.r.t. Hive(スパークではありません):Hiveヒント
MAPJOIN
を使用すると、以下のような同様のことが実現できます...
_Select /*+ MAPJOIN(b) */ a.key, a.value from a join b on a.key = b.key
Hive> set Hive.auto.convert.join=true;
Hive> set Hive.auto.convert.join.noconditionaltask.size=20971520
Hive> set Hive.auto.convert.join.noconditionaltask=true;
Hive> set Hive.auto.convert.join.use.nonstaged=true;
Hive> set Hive.mapjoin.smalltable.filesize = 30000000; // default 25 mb made it as 30mb
_
さらに読む:私の BHJ、SHJ、SMJに関する記事 を参照してください
left.join(broadcast(right), ...)
を使用して、データフレームがブロードキャストされるようにヒントを出すことができます
設定spark.sql.autoBroadcastJoinThreshold = -1
はブロードキャストを完全に無効にします。 Spark SQL、DataFrames and Datasets Guide のその他の設定オプション)を参照してください。
これは現在のスパークの制限です。 SPARK-6235 を参照してください。 2GBの制限は、ブロードキャスト変数にも適用されます。
これを行う他の良い方法はありませんか?異なるパーティション?
それ以外の場合は、それぞれ<2GBである複数のブロードキャスト変数を手動で作成することにより、回避することができます。
このコードは、Spark 2.11バージョン2.0.0のBroadcast Joinで機能します。
import org.Apache.spark.sql.functions.broadcast
val employeesDF = employeesRDD.toDF
val departmentsDF = departmentsRDD.toDF
// materializing the department data
val tmpDepartments = broadcast(departmentsDF.as("departments"))
import context.implicits._
employeesDF.join(broadcast(tmpDepartments),
$"depId" === $"id", // join by employees.depID == departments.id
"inner").show()
上記のコードのリファレンスは次のとおりです Henning Kroppブログ、Sparkによるブロードキャスト参加