spark三种join机制

本文详细介绍了Spark中的三种Join策略:BroadcastHashJoin用于避免大表shuffle,ShuffleHashJoin基于分区并行计算,SortMergeJoin在大数据量下提供稳定性能。讨论了每种策略的适用场景和优缺点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Spark通常使用三种Join策略方式:

  • Broadcast Hash Join(BHJ)
  • Shuffle Hash Join(SHJ)
  • Sort Merge Join(SMJ)

1. Broadcast Hash Join

在数据库的常见模型中(比如星型模型或者雪花模型),表一般分为两种:事实表和维度表。维度表一般指固定的、变动较少的表,例如联系人、物品种类等,一般数据有限。而事实表一般记录流水,比如销售清单等,通常随着时间的增长不断膨胀。

因为join操作是对两个表中key值相同的记录进行连接,在spark SQL中,对两个表做join最直接的方式是先根据key分区,再在每个分区中把key值相同的记录拿出来做连接操作。但这样就不可避免地涉及到shuffle,而shuffle在spark中是比较耗时的操作,我们应该尽可能的设计spark应用使其避免大量的shuffle。

当维度表和事实表进行join操作时,为了避免shuffle,我们可以将大小有限的维度表的全部数据分发到每个节点上,供事实表使用。executor存储维度表的全部数据,一定程度上牺牲了空间,换取shuffle操作大量的耗时,这在spark SQL中称为Broadcast Join. 看起来广播时一个比较理想的方案,但它有没有缺点呢?也很明显,这个方案只能用于广播较小的表,否则数据的冗余传输就远大于shuffle的开销;另外,广播时需要将被广播的表先collect到driver端,当频繁有广播出现时,对driver的内存也是一个考验。

进一步说明:
当小表与大表进行Join操作时,为了避免shuffle操作,将小表的所有数据分发到每个节点与大表进行Join操作,尽管牺牲了空间,但是避免了耗时的Shuffle操作。

表需要broadcast,那么必须小于spark.sql.autoBroadcastJoinThreshold配置的值(默认是10M),或者明确添加broadcast join hint。

1. base table不能broadcast,例如在left outer join中,仅仅right表可以broadcast

2. 这种算法仅仅用来broadcast小表,否则数据的传输可能比shuffle操作成本高

3. broadcast也需要到driver,如果有太多的broadcast,对driver内存也是压力

2. Shuffle Hash Join

由于spark是一个分布式的计算引擎,可以通过分区的形式将大批量的数据划分成n份较小的数据集进行并行计算。这种思想应用到join上便是shuffle hash join了。利用key相同必然分区相同的原理,spark SQL将较大表的join分而治之,先将表划分成n个分区,再对两个表中相对应分区的数据分别进行hash join。

shuffle hash join分为两步:

对两张表分别按照join keys进行分区,即shuffle,目的是为了让有相同join keys值的记录分到对应的分区中。


对对应分区中的数据进行join,此处先将小表分区构造一张hash表,然后根据大表分区中记录的join keys值拿出来进行匹配。

3. Sort Merge Join

上面两种发现适应一定大小的表,但是当两张表足够大时,上面方法对内存造成很大压力,这是因为当两张表做Hash Join时,其中一张表必须完成加载到内存中。

当两张表很大时,Spark SQL使用一种新的算法来做Join操作,叫做Sort Merge Join,这种算法并不会加载所有的数据,然后开始Hash Join,而是在Join之前进行数据排序。

首先将两张表按照join key进行了重新shuffle,保证join keys值相同的记录会被分在相同的分区。


分区后对每个分区内的数据进行排序,排序后再对相应的分区内的记录进行连接。

因为两个序列都是有序的,从头遍历,碰到key相同的就输出;如果不同,左边小就继续取左边,反之取右边。

可以看出,无论分区有多大,Sort Merge Join都不用把某一侧的数据全部加载到内存中,而是即用即丢,从而大大提升了大数据量下SQL JOIN的稳定性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值