Spark正在广播不适合广播的大型数据集

时间:2019-05-16 13:01:06

标签: apache-spark

我正在使用Spark 2.3.0,我有2个数据集,它们都相当大,超过400 MB。当我加入这些Spark时,尝试广播其中之一。列数较少的那一列(如果它仍然有助于识别RCA)。它失败,原因如下:java.util.concurrent.TimeoutException:[300秒]错误之后,由于我具有相关配置的默认设置,期货超时。

我具有spark.sql.broadcastTimeout和spark.sql.autoBroadcastJoinThreshold的默认设置(10 MB);我不想尽可能地禁用广播。

在分类时,我发现如果我设置broadcastTimeout> 60可以,但是随着数据集大小的增加它不会起作用。不确定为什么spark不遵守autoBroadcastJoinThreshold吗?

我不使用配置单元metastore,我的文件存储在HDFS上,我为它们使用架构。

尝试添加虚拟列,因为我相信奇迹:)

    Dataset<Row> MergedById = fromValidFromField.as("df1")
            .join(filteredByMailIds.as("df2"),
                    col("df1.id")
                            .equalTo(col("df2.id")),"inner")

这是导致广播的联接

1 个答案:

答案 0 :(得分:1)

Spark决定通过估计数据集上的操作(如过滤器等)之后的数据大小来进行广播,而不使用数据集的实际大小。

例如:假设b(id:Int,name:String)是1GB(>广播阈值)大小的表。

select * from a join b ON a.id = b.id AND b.id < 100

在上面的示例中,由于联接操作中实际涉及的数据(假设有100个唯一行)非常少,并且将小于默认阈值,因此上次使用的联接策略将是广播 10MB。

通过对计划进行自省,我们可以找到广播的数据大小。

Let plan: LogicalPlan = df.queryExecution.optimizedPlan
val size = df.find(_.isInstanceOf[org.apache.spark.sql.catalyst.plans.logical.Join])
.get
.stats
.sizeInBytes

这应该提示是否遵守广播阈值。(以上代码假定查询中只有一个联接操作)