【Spark】Spark Join类型及Join实现方式
如果觉得这篇文章对您有帮助,别忘了点赞、分享或关注哦!您的一点小小支持,不仅能帮助更多人找到有价值的内容,还能鼓励我持续分享更多精彩的技术文章。感谢您的支持,让我们一起在技术的世界中不断进步!
Spark Join类型
1. Inner Join (内连接)
- 示例:
val result = df1.join(df2, df1("id") === df2("id"), "inner")
- 执行逻辑:只返回那些在两个表中都有匹配的行。
2. Left Join (左外连接)
- 示例:
val result = df1.join(df2, df1("id") === df2("id"), "left")
- 执行逻辑:返回左表的所有记录,并且右表的匹配行,若右表没有匹配行则返回
null
。
3. Right Join (右外连接)
- 示例:
val result = df1.join(df2, df1("id") === df2("id"), "right")
- 执行逻辑:返回右表的所有记录,并且左表的匹配行,若左表没有匹配行则返回
null
。
4. Full Join (全外连接)
- 示例:
val result = df1.join(df2, df1("id") === df2("id"), "outer")
- 执行逻辑:返回左表和右表的所有记录,若某一方没有匹配,另一方则填充
null
。
5. Left Semi Join (左半连接)
- 示例:
val result = df1.join(df2, df1("id") === df2("id"), "left_semi")
- 执行逻辑:返回左表中与右表匹配的行,只返回左表数据,不返回右表。
6. Left Anti Join (左反连接)
- 示例:
val result = df1.join(df2, df1("id") === df2("id"), "left_anti")
- 执行逻辑:返回左表中不与右表匹配的行。
7. Cross Join (笛卡尔积连接)
- 示例:
val result = df1.crossJoin(df2)
- 执行逻辑:返回两表的笛卡尔积,左表的每一行与右表的每一行组合。
Spark Join实现方式
在 Spark 中,
Join
操作有多种实现方式,每种方式的实现原理、适用场景和执行性能有所不同。接下来我们详细讨论以下几种常见的
Join
实现方式:
1. CPJ(Cartesion Product Join)笛卡尔积连接
工作原理:
- 笛卡尔积连接是最基础的连接方式,它将两个数据集的每一条记录与另一个数据集的每一条记录进行配对,从而生成一个新的结果集。这个操作是非常低效的,因为它会产生
N * M
条记录(N
和M
分别是两个数据集的行数)。- 这种方式不需要连接条件,因此通常不是我们期望的连接类型。
执行性能:
- 效率低:当两个数据集的大小很大时,计算量将急剧增加。通常,笛卡尔积连接仅在明确需要时使用(例如,计算所有可能的配对)。
Spark 选择笛卡尔积的情况:
- 笛卡尔积连接在 Spark 中通常是显式调用
crossJoin()
时使用。2. SMJ(Shuffle Sort Merge Join)排序归并连接
工作原理:
- 排序归并连接首先对两个数据集按照连接键进行排序,然后使用
merge
操作将排序后的数据集进行合并。数据集会被按连接键进行shuffle
,然后在每个分区内执行归并操作。- 这种方法非常适合处理大规模的分布式数据,尤其是当两个数据集都很大并且有良好的分区时。
执行性能:
- 效率较高:适合大数据量的连接,尤其当连接键有排序特性时。
- 由于需要对数据进行排序和
shuffle
,这会增加网络和磁盘的 I/O 成本。Spark 选择 SMJ 的情况:
- 当数据集较大并且 Spark 能够进行有效的
shuffle
操作时,Spark 会选择SMJ
。- 如果连接的表已经分区或有排序字段,则 Spark 会优先选择该方式。
3. SHJ(Shuffle Hash Join)哈希连接
工作原理:
- 哈希连接(SHJ) 是一种基于哈希表的连接方式。其基本思想是将一个表(通常是较小的表)哈希到内存中,然后通过哈希表查找另一个表的匹配记录。该方法特别适合处理大规模的数据集,尤其是当连接的两个数据集都比较大时,或者当连接键不具有顺序或排序特性时。
- 执行步骤:
- 分区阶段(Shuffle):首先,Spark 会将两个数据集根据连接键进行
shuffle
(重分区),确保具有相同连接键的记录被发送到同一个节点。此时,数据会按照连接键进行重分区。- 构建哈希表:选择较小的表(通常是内表),在每个节点上对该表进行哈希,构建哈希表。哈希表存储连接键及其对应的记录。
- 匹配查找:然后,在同一个节点上扫描较大的表(外表),对于每一条记录,使用相同的连接键查找哈希表中的匹配项。如果匹配,则生成结果。
执行性能:
- 高效:相比传统的嵌套循环连接(
NLJ
),哈希连接通常在处理大数据集时更为高效,特别是当连接条件是等值连接时。Spark 选择 SHJ 的情况:
- 外表大小至少是内表的3倍且内表的数据分片平均大小要小于广播变量阈值,Spark 会选择 Shuffle Hash Join。
4. BNLJ(Broadcast Nested Loop Join)广播嵌套循环连接
工作原理:
- 广播嵌套循环连接是嵌套循环连接的一种优化形式,针对连接的一个表较小的情况。它首先将较小的表(通常是内表)广播到所有执行节点,然后对大表(通常是外表)进行扫描。在每个节点上,将小表加载到内存中,并在每个分区上与外表进行连接。
执行性能:
- 高效:相比于传统的嵌套循环连接(
Nested Loop Join
),广播嵌套循环连接的效率较高,因为它通过将小表广播到每个节点,避免了全局的shuffle
操作,减少了数据传输的延迟。- 适合当一个表非常小(例如,
broadcast()
小表时)时,执行性能特别好。Spark 选择 BNLJ 的情况:
- Spark 会自动选择 Broadcast Nested Loop Join,当数据集中的一个表较小(可以放入内存)时,Spark 会选择该表进行广播,从而提高连接操作的性能。通常,Spark
会根据表的大小和内存限制来决定是否使用广播join
。5. BHJ(Broadcast Hash Join)广播哈希连接
工作原理:
- 广播哈希连接通过将一个小表广播到所有执行节点,从而避免了全局的
shuffle
操作。大的数据集会被分配到多个节点,而小的数据集会被广播到每个节点。- 这种方式非常高效,适用于连接一个大表和一个小表的情况。
执行性能:
- 效率非常高:适用于大表和小表连接,避免了大规模的
shuffle
操作。- 适合当一个表非常小(例如,
broadcast()
小表时)时,执行性能特别好。Spark 选择 BHJ 的情况:
- 如果其中一个表很小,Spark 会选择
BHJ
,因为将小表广播到所有节点可以大大减少shuffle
的开销。Spark 如何选择
Join
策略?1. 等值 Join
在等值数据关联中,Spark 会尝试按照以下顺序选择最优的连接策略:
- BHJ(Broadcast Hash Join)
- SMJ(Shuffle Sort Merge Join)
- SHJ(Shuffle Hash Join)
适用场景:
- BHJ(Broadcast Hash Join): 连接类型不能是全连接(Full Outer Join),基表需要足够小,能够放入内存并通过广播发送到所有节点。
- SMJ(Shuffle Sort Merge Join)与 SHJ(Shuffle Hash Join):支持所有连接类型,如Full Outer Join,Anti join
为什么SHJ比SMJ执行效率高,排名却不如SMJ靠前
- 相比 SHJ,Spark优先选择SMJ的原因在于,SMJ的实现方式更加稳定,更不容易OOM
- 在 Spark 中,SHJ(Shuffle Hash Join) 策略要想被选中,需要满足以下两个先决条件:
- a. 外表大小至少是内表的 3 倍:只有当内外表的尺寸悬殊到一定程度时,SHJ 的性能优势才会明显超过 SMJ。
- b. 内表的数据分片平均大小要小于广播变量阈值:内表的数据分片必须足够小,以便能够通过广播传递到各个节点,而不引起内存溢出或性能问题。
- 相比 SHJ,SMJ没有这么多的附加条件,无论是单表排序,还是两表做归并关联,都可以借助磁盘来完成。内存中放不下的数据,可以临时溢出到磁盘
2. 非等值 Join
- 在非等值数据关联中,Spark可选的Join策略只有BNLJ(Broadcast Nested Loop Join)和CPJ(Cartesion Product Join),BNLJ适合内表满足广播情况,否则只能用CPJ兜底
相关文章:

【Spark】Spark Join类型及Join实现方式
如果觉得这篇文章对您有帮助,别忘了点赞、分享或关注哦!您的一点小小支持,不仅能帮助更多人找到有价值的内容,还能鼓励我持续分享更多精彩的技术文章。感谢您的支持,让我们一起在技术的世界中不断进步! Sp…...
meta llama 大模型一个基础语言模型的集合
LLaMA 是一个基础语言模型的集合,参数范围从 7B 到 65B。我们在数万亿个 Token 上训练我们的模型,并表明可以专门使用公开可用的数据集来训练最先进的模型,而无需诉诸专有的和无法访问的数据集。特别是,LLaMA-13B 在大多数基准测试…...

JAVA爬虫获取1688关键词接口
以下是使用Java爬虫获取1688关键词接口的详细步骤和示例代码: 一、获取API接口访问权限 要使用1688关键词接口,首先需要获取API的使用权限,并了解接口规范。以下是获取API接口的详细步骤: 注册账号:在1688平台注册一…...
操作系统——内存管理
1、什么是虚拟内存?它是如何实现的?虚拟内存与物理内存之间有什么关系? 虚拟内存是操作系统提供的一种内存管理机制,它使程序认为自己拥有连续的内存空间,但实际上内存可能被分散存储在物理内存和磁盘交换空间中。 虚…...
android studio 模拟器不能联网?
模拟器路径: C:\Users\Administrator\AppData\Local\Android\Sdk\emulator\emulator.exe.关闭所有AVD设备实例 导航至: C:\Users\userName\AppData\Local\Android\Sdk\emulator查看模拟器名称 AdministratorDESKTOP-6JB1OGC MINGW64 ~/AppData/Local/…...
CTF-WEB: 目录穿越与模板注入 [第一届国城杯 Ez_Gallery ] 赛后学习笔记
step1 验证码处存在逻辑漏洞,只要不申请刷新验证码就一直有效 字典爆破得到 admin:123456 step2 /info?file../../../proc/self/cmdline获得 python/app/app.py经尝试,读取存在的目录时会返回 A server error occurred. Please contact the administrator./info?file.…...

数据结构6.4——归并排序
基本思想: 归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法的一个非常典型的应用。将已有的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个…...
【html 常用MIME类型列表】
本表仅列出了常用的MIME类型,完整列表参考文档。 浏览器通常使用 MIME 类型(而不是文件扩展名)来确定如何处理 URL,因此 Web 服务器在响应头中添加正确的 MIME 类型非常重要。 如果配置不正确,浏览器可能会曲解文件内容…...

Linux之vim编辑器
vi编辑器是所有Unix及linux系统下标准的编辑器,类似于Windows系统下的记事本。很多软件默认使用vi作为他们编辑的接口。vim是进阶版的vi,vim可以视为一种程序编辑器。 前言: 1.文件准备 复制 /etc/passwd文件到自己的目录下(不…...

【工具介绍】可以批量查看LableMe标注的图像文件信息~
在图像处理和计算机视觉领域,LabelMe是一个广泛使用的图像标注工具,它帮助我们对图像中的物体进行精确的标注。但是,当标注完成后,我们常常需要一个工具来批量查看这些标注信息。 今天,我要介绍的这款exe程序…...
2024年山西省第十八届职业院校技能大赛 (高职组)“信息安全管理与评估”赛项规程
2024年山西省第十八届职业院校技能大赛 (高职组)“信息安全管理与评估”赛项规程 一、赛项名称 赛项名称:信息安全管理与评估 英文名称:Information Security Management and Evaluation 赛项组别:高职教师组 赛项归属…...

STM32完全学习——STemWin的移植小插曲
一、移植编译的一些问题 新版的STemWin的库没有区别编译器,只有一些这样的文件,默认你将这些文件导入到KEIL中,然后编译就会有下面的错误。 ..\MEWIN\STemWin\Lib\STemWin_CM4_wc16.a(1): error: A1167E: Invalid line start ..\MEWIN\STe…...

Java——IO流(下)
一 (字符流扩展) 1 字符输出流 (更方便的输出字符——>取代了缓冲字符输出流——>因为他自己的节点流) (PrintWriter——>节点流——>具有自动行刷新缓冲字符输出流——>可以按行写出字符串,并且可通过println();方法实现自动换行) 在Java的IO流中…...
avue-crud 同时使用 column 与 group 的问题
场景一:在使用option 中的column 和 group 进行表单数据新增操作时,进行里面的控件操作时,点击后卡死问题,文本没问题 其它比如下拉,单选框操作,当删除 column 中的字段后, group 中的可以操作 …...
深入解析 Pytest 中的 conftest.py:测试配置与复用的利器
在 Pytest 测试框架中,conftest.py 是一个特殊的文件,用于定义测试会话的共享配置和通用功能。它是 Pytest 的核心功能之一,可以用于以下目的: 【主要功能】 1、定义共享的 Fixture (1)conftest.py 文件可…...

JAVA |日常开发中Websocket详解
JAVA |日常开发中Websocket详解 前言一、Websocket 概述1.1 定义1.2 优势 二、Websocket 协议基础2.1 握手过程2.2 消息格式2.3 数据传输方式 三、Java 中使用 Websocket3.1 Java WebSocket API(JSR - 356)3.2 第三方库(如 Tyrus&…...

Typora教程
目录 一、下载安装 二、激活 1.激活 2.解决激活提示窗口 一、下载安装 去官网下载Typora安装,我的是1.9.5版本 二、激活 1.激活 根据路径找到Typora/resources/page-dist/static/js 使用记事本打开LicenseIndex文件,如下图: 按住快捷…...

泛微E9常见API保姆级详解!!!!
前言 在泛微前端开发过程中,虽然大部分是对流程以及流程逻辑的调整,但是还是会有一些小的个性化需求是需要借助JS来实现的。 比如:对同一组数据,前后变化不一样时,需要对这组变化后的数据进行标红处理;对提…...
UniApp配置使用原子化tailwindcss
参考视频 创建项目 新建项目选择uniapp - vue版本这里我选择3 - 点击创建即可 创建完成后,如果是要编译到小程序的项目则可以先将项目运行到小程序打开了 初始化package.json 执行 npm init -y安装和配置 安装 npm i -D tailwindcss postcss autoprefixer # 安…...

02. Docker:安装和操作
目录 一、Docker的安装方式 1、实验环境准备 1.1 关闭防火墙 1.2 可以访问网络 1.3 配置yum源 2、yum安装docker 2.1 安装docker服务 2.2 配置镜像加速 2.3 启动docker服务 3、二进制安装docker 3.1 下载或上传安装包并解压 3.2 配置使用systemctl管理 3.3 配置镜像…...

国防科技大学计算机基础课程笔记02信息编码
1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制,因此这个了16进制的数据既可以翻译成为这个机器码,也可以翻译成为这个国标码,所以这个时候很容易会出现这个歧义的情况; 因此,我们的这个国…...
rknn优化教程(二)
文章目录 1. 前述2. 三方库的封装2.1 xrepo中的库2.2 xrepo之外的库2.2.1 opencv2.2.2 rknnrt2.2.3 spdlog 3. rknn_engine库 1. 前述 OK,开始写第二篇的内容了。这篇博客主要能写一下: 如何给一些三方库按照xmake方式进行封装,供调用如何按…...

【网络安全产品大调研系列】2. 体验漏洞扫描
前言 2023 年漏洞扫描服务市场规模预计为 3.06(十亿美元)。漏洞扫描服务市场行业预计将从 2024 年的 3.48(十亿美元)增长到 2032 年的 9.54(十亿美元)。预测期内漏洞扫描服务市场 CAGR(增长率&…...

【JVM】- 内存结构
引言 JVM:Java Virtual Machine 定义:Java虚拟机,Java二进制字节码的运行环境好处: 一次编写,到处运行自动内存管理,垃圾回收的功能数组下标越界检查(会抛异常,不会覆盖到其他代码…...

Linux-07 ubuntu 的 chrome 启动不了
文章目录 问题原因解决步骤一、卸载旧版chrome二、重新安装chorme三、启动不了,报错如下四、启动不了,解决如下 总结 问题原因 在应用中可以看到chrome,但是打不开(说明:原来的ubuntu系统出问题了,这个是备用的硬盘&a…...
【HTML-16】深入理解HTML中的块元素与行内元素
HTML元素根据其显示特性可以分为两大类:块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...

成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战
在现代战争中,电磁频谱已成为继陆、海、空、天之后的 “第五维战场”,雷达作为电磁频谱领域的关键装备,其干扰与抗干扰能力的较量,直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器,凭借数字射…...
LangChain知识库管理后端接口:数据库操作详解—— 构建本地知识库系统的基础《二》
这段 Python 代码是一个完整的 知识库数据库操作模块,用于对本地知识库系统中的知识库进行增删改查(CRUD)操作。它基于 SQLAlchemy ORM 框架 和一个自定义的装饰器 with_session 实现数据库会话管理。 📘 一、整体功能概述 该模块…...

【电力电子】基于STM32F103C8T6单片机双极性SPWM逆变(硬件篇)
本项目是基于 STM32F103C8T6 微控制器的 SPWM(正弦脉宽调制)电源模块,能够生成可调频率和幅值的正弦波交流电源输出。该项目适用于逆变器、UPS电源、变频器等应用场景。 供电电源 输入电压采集 上图为本设计的电源电路,图中 D1 为二极管, 其目的是防止正负极电源反接, …...
C#中的CLR属性、依赖属性与附加属性
CLR属性的主要特征 封装性: 隐藏字段的实现细节 提供对字段的受控访问 访问控制: 可单独设置get/set访问器的可见性 可创建只读或只写属性 计算属性: 可以在getter中执行计算逻辑 不需要直接对应一个字段 验证逻辑: 可以…...