Spark 的三种join方式

本文详细介绍了Spark中hashjoin、broadcastjoin和shufflejoin的原理,重点讲解了为何选择小表构建hashtable,并讨论了broadcastjoin在维表join中的应用以及shufflejoin和sort-mergejoin在大数据场景的使用。

参考博客:https://www.cnblogs.com/duodushuduokanbao/p/9911256.html

Spark的join实现方案有三种:

  • broadcast hash join
  • shuffle hash join
  • sort-merge join

hash join

确定 小表(Bulid Table) 和 大表(Probe Table),利用小表 根据 key 进行hash,建立hash table,大表同样对key进行相同的hash,映射hash table中的记录,如果映射成功且join条件符合,则将数据进行关联。

为什么 bulid table 选择小表, probe table 选择大表? 因为在构建 hash table 时最好能将其全部加载到内存,这样才效率最高,这也说明了为什么 hash join 算法只适合至少有一个小表的场景,对于两个大表的join 场景并不适用,两个大表的 join ,可选用 sort merge join。

hash join主要针对单机,以下两种是对hash join的分布式改造后

Broadcast join

一般用于维表和实时表进行join,可将维表(一般不超过10M)发送至各个节点,使各个节点都存有一份完整的维表数据,接下来相当于单机进行hash join。

SparkSQL 也可以根据内存资源、带宽资源适量将参数 spark.sql.autoBroadcastJoinThreshold(默认是 10M) 调大,让更多 join 实际执行为 broadcast hash join。

shuffle join

当join的两张表数据量都很大时,利用 key相同的数据将会被分到相同分区上 的原理,将两张表按key进行分区,使相同key的记录分到同一个节点上,然后在对每个节点上的数据进行hash join

sort-merge join(没太理解)

和shuffle join一样,将两张大表join key进行重分区,对每个分区的节点进行排序,然后对排好序的表进行join,join的操作:分表遍历两个有序序列,碰到相同的key就merge然后输出

 

 

 

 

<think>好的,我现在需要回答用户关于Spark中5种Join策略及其使用场景的问题。首先,我得回忆一下Spark的几种Join策略,可能包括Shuffle Hash Join、Broadcast Hash Join、Sort Merge Join、Broadcast Nested Loop Join和Cartesian Product Join?或者可能有其他策略,比如Skew Join?不过Skew Join可能属于优化后的策略,而不是基础策略。 用户提到了5种,所以需要确认正确的五种。根据之前的引用,用户提供的参考里有提到BHJ(Broadcast Hash Join),Skew Join,还有可能Shuffle Hash Join、Sort Merge Join和Broadcast Nested Loop Join。或者可能包括Cartesian Join?或者还有其他的? 让我仔细想想。根据Spark官方文档,常见的Join策略包括: 1. Broadcast Hash Join (BHJ) 2. Shuffle Hash Join 3. Sort Merge Join (SMJ) 4. Cartesian Product Join 5. Broadcast Nested Loop Join 可能这五种是主要的。此外,Skew Join可能是一种优化手段,而不是基本策略。用户的问题是需要5种策略,所以可能需要列举这五种。 接下来需要详细描述每种策略的原理、适用场景,以及可能的代码示例或配置方式。例如,Broadcast Hash Join适用于小表,当其中一个表足够小可以被广播到所有节点使用,这样可以避免Shuffle。而Shuffle Hash Join则需要两个表都不太大,因为需要将数据按Join Key进行分区,并在每个分区内构建哈希表。Sort Merge Join通常用于大规模数据,且数据已经排序的情况,这是Spark默认的Join策略,因为适合分布式处理。Cartesian Product Join是笛卡尔积,性能最差,适用于没有Join条件的情况。Broadcast Nested Loop Join可能是在某些特定条件下的选择,比如非等值连接,并且其中一张表很小的情况。 需要确保每个策略的说明准确,并结合用户提供的引用内容。例如,引用[1]提到当小表存在选择BHJ,引用[2]关于Skew Join处理数据倾斜,但用户的问题可能更关注基础策略,所以可能Skew Join不在五种里。引用[3]中的代码示例可能涉及不同的Join类型,但策略可能不同。 另外,用户可能需要知道如何触发这些策略,例如通过设置参数(如自动广播的阈值)或使用HINT。例如,Spark.sql.autoBroadcastJoinThreshold参数控制BHJ的使用。 现在要组织这些信息,分成五个部分,每个策略的名称、原理、适用场景,可能的使用方式或示例。同,生成相关问题,例如性能优化、如何选择策略、处理数据倾斜等。 需要检查是否有遗漏的策略,或者是否有更常用的策略名称。例如,Shuffle Hash Join和Sort Merge Join的区别,前者需要哈希表,后者需要排序。在Spark中,默认情况下可能优先使用Sort Merge Join,因为Shuffle Hash Join需要较大的内存,而Sort Merge Join更适合大规模数据。 另外,注意用户可能需要知道每种策略的优缺点,比如BHJ的网络开销小,但要求表足够小;Sort Merge Join的扩展性好,但需要排序可能带来额外开销。 总结下来,五个策略应该是: 1. Broadcast Hash Join (BHJ) 2. Shuffle Hash Join (SHJ) 3. Sort Merge Join (SMJ) 4. Cartesian Product Join 5. Broadcast Nested Loop Join (BNLJ) 或者可能还有其他?比如,在Spark 3.0之后有没有新增的策略?比如可能引入的Shuffle Sort Merge Join或者其他的?不过用户可能期望的是基础的五种,所以先按这五种来写。 在适用场景中,BHJ适用于小表,SHJ适用于中等大小的表,SMJ适用于大表,Cartesian用于无条件Join,BNLJ可能用于非等值连接且其中一表小的情况。 现在需要详细展开每个部分,确保正确性,并引用相关参考。例如,引用[1]提到当小表存在选择BHJ,这适用于BHJ的场景。引用[2]中的Skew Join可能是在处理数据倾斜对SMJ的优化,但可能不算作基础策略。 最后生成相关问题,例如如何选择策略,优化Join性能,处理数据倾斜等。</think>### Spark 5种 Join 策略详解及适用场景 在Spark中,Join策略的选择直接影响计算性能和资源利用率。以下是Spark支持的5种核心Join策略及其适用场景: --- #### 1. **Broadcast Hash Join (BHJ)** - **原理**:将小表广播到所有Executor节点,在每个节点上与大表的分区数据进行哈希匹配。 数学表达式:假设小表大小为$S$,广播后每个节点执行哈希查找的间复杂度为$O(S)$。 - **适用场景**: - 其中一个表的数据量**小于** `spark.sql.autoBroadcastJoinThreshold`(默认10MB)[^1]。 - **等值Join**且无需全局Shuffle。 - **触发方式**: ```sql -- 使用HINT强制广播 SELECT /*+ BROADCAST(small_table) */ * FROM large_table JOIN small_table ON ... ``` --- #### 2. **Shuffle Hash Join (SHJ)** - **原理**:对两个表按Join Key进行Shuffle分区,在每个分区内构建哈希表进行匹配。 公式化:若两表分别分$N$个区,每个分区的哈希表构建间为$O(K/N)$,$K$为表大小。 - **适用场景**: - 两表**均较大**但单分区数据可放入内存。 - 等值Join且无数据倾斜。 - **限制**:需手动开启(默认关闭,因内存压力大): ```sql SET spark.sql.join.preferSortMergeJoin=false; ``` --- #### 3. **Sort Merge Join (SMJ)** - **原理**:通过Shuffle将数据按Key排序后,在有序数据集上进行归并查找。 间复杂度:$O(N \log N)$(排序) + $O(N)$(归并)。 - **适用场景**: - **大规模数据集**的等值JoinSpark默认策略)[^3]。 - 数据已按Join Key预排序效率更高。 - **优化**:应对数据倾斜可使用`Skew Join`(拆分倾斜Key为多个子任务)[^2]。 --- #### 4. **Broadcast Nested Loop Join (BNLJ)** - **原理**:广播小表,对大表逐行扫描进行笛卡尔积匹配(支持非等值条件)。 性能公式:$O(S \times L)$,$S$为小表大小,$L$为大表行数。 - **适用场景**: - **非等值Join**(如`a.col1 > b.col2`)。 - 小表可广播且大表规模可控。 - **缺点**:计算复杂度高,需谨慎使用。 --- #### 5. **Cartesian Product Join** - **原理**:直接计算两表的笛卡尔积,无任何优化。 公式:结果集大小为$M \times N$($M$和$N$为两表行数)。 - **适用场景**: - **无Join条件**的跨表关联。 - 测试或极小数据集场景。 - **触发条件**:显式使用`CROSS JOIN`语法。 --- ### 策略选择流程图 ```plaintext 是否等值Join? ├─ 是 → 能否广播小表? → BHJ ├─ 否 → BNLJ或Cartesian ├─ 中等规模 → SHJ └─ 大规模 → SMJ(默认) ``` ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值