数据分析中将两个数据集进行 Join 操作是很常见的场景。在 Spark 的物理计划阶段,Spark 的 Join Selection 类会根

据 Join hints 策略、Join 表的大小、 Join 是等值 Join 还是不等值以及参与 Join 的 key 是否可以排序等条件来选择最

终的 Join 策略,最后 Spark 会利用选择好的 Join 策略执行最终的计算。当前 Spark 一共支持五种 Join 策略:

  • Broadcast hash join (BHJ)

  • Shuffle hash join(SHJ)

  • Shuffle sort merge join (SMJ)

  • Shuffle-and-replicate nested loop join,又称笛卡尔积(Cartesian product join)

  • Broadcast nested loop join (BNLJ)

其中 BHJ SMJ 这两种 Join 策略是我们运行 Spark 作业最常见的。JoinSelection 会先根据 Join 的 Key 为等值 Join

来选择 Broadcast hash joinShuffle hash join 以及 Shuffle sort merge join 中的一个;如果 Join 的 Key 为不等值

Join 或者没有指定 Join 条件,则会选择 Broadcast nested loop joinShuffle-and-replicate nested loop join

不同的 Join 策略在执行上效率差别很大,了解每种 Join 策略的执行过程和适用条件是很有必要的。

1、Broadcast Hash Join

Broadcast Hash Join 的实现是将小表的数据广播到 Spark 所有的 Executor 端,这个广播过程和我们自己去广播数

据没什么区别:

利用 collect 算子将小表的数据从 Executor 端拉到 Driver 端

在 Driver 端调用 sparkContext.broadcast 广播到所有 Executor 端

在 Executor 端使用广播的数据与大表进行 Join 操作(实际上是执行map操作)

这种 Join 策略避免了 Shuffle 操作。一般而言,Broadcast Hash Join 会比其他 Join 策略执行的要快。

使用这种 Join 策略必须满足以下条件:

小表的数据必须很小,可以通过 spark.sql.autoBroadcastJoinThreshold 参数来配置,默认是 10MB

如果内存比较大,可以将阈值适当加大

spark.sql.autoBroadcastJoinThreshold 参数设置为 -1,可以关闭这种连接方式

只能用于等值 Join,不要求参与 Join 的 keys 可排序

2、Shuffle Hash Join

当表中的数据比较大,又不适合使用广播,这个时候就可以考虑使用 Shuffle Hash Join

Shuffle Hash Join 同样是在大表和小表进行 Join 的时候选择的一种策略。它的计算思想是:把大表和小表按照相同

的分区算法和分区数进行分区(根据参与 Join 的 keys 进行分区),这样就保证了 hash 值一样的数据都分发到同一

个分区中,然后在同一个 Executor 中两张表 hash 值一样的分区就可以在本地进行 hash Join 了。在进行 Join 之

前,还会对小表的分区构建 Hash Map。Shuffle hash join 利用了分治思想,把大问题拆解成小问题去解决。

要启用 Shuffle Hash Join 必须满足以下条件:

仅支持等值 Join,不要求参与 Join 的 Keys 可排序

spark.sql.join.preferSortMergeJoin 参数必须设置为 false,参数是从 Spark 2.0.0 版本引入的,默认值为

true,也就是默认情况下选择 Sort Merge Join

小表的大小(plan.stats.sizeInBytes)必须小于 spark.sql.autoBroadcastJoinThreshold *

spark.sql.shuffle.partitions(默认值200)

而且小表大小(stats.sizeInBytes)的三倍必须小于等于大表的大小(stats.sizeInBytes),也就是

a.stats.sizeInBytes * 3 < = b.stats.sizeInBytes

3、Shuffle Sort Merge Join

前面两种 Join 策略对表的大小都有条件的,如果参与 Join 的表都很大,这时候就得考虑用 Shuffle Sort Merge Join

了。

Shuffle Sort Merge Join 的实现思想:

将两张表按照 join key 进行shuffle,保证join key值相同的记录会被分在相应的分区

对每个分区内的数据进行排序

排序后再对相应的分区内的记录进行连接

无论分区有多大,Sort Merge Join都不用把一侧的数据全部加载到内存中,而是即用即丢;因为两个序列都有序。从

头遍历,碰到key相同的就输出,如果不同,左边小就继续取左边,反之取右边。从而大大提高了大数据量下sql join

的稳定性。

要启用 Shuffle Sort Merge Join 必须满足以下条件:

仅支持等值 Join,并且要求参与 Join 的 Keys 可排序

4、Cartesian product join

如果 Spark 中两张参与 Join 的表没指定连接条件,那么会产生 Cartesian product join,这个 Join 得到的结果其实

就是两张表行数的乘积。

5、Broadcast nested loop join

可以把 Broadcast nested loop join 的执行看做下面的计算:

for record_1 in relation_1:

for record_2 in relation_2:

join condition is executed

可以看出 Broadcast nested loop join 在某些情况会对某张表重复扫描多次,效率非常低下。从名字可以看出,这种

join 会根据相关条件对小表进行广播,以减少表的扫描次数。

Broadcast nested loop join 支持等值和不等值 Join,支持所有的 Join 类型。

吴邪,小三爷,混迹于后台,大数据,人工智能领域的小菜鸟。

更多请关注

大数据开发-Spark Join原理详解的更多相关文章

  1. 大数据开发-linux下常见问题详解

    1.user ss is currently user by process 3234 问题原因:root --> ss --> root 栈递归一样 解决方式:exit 退出当前到ss再 ...

  2. 大数据入门第八天——MapReduce详解(三)MR的shuffer、combiner与Yarn集群分析

    /mr的combiner /mr的排序 /mr的shuffle /mr与yarn /mr运行模式 /mr实现join /mr全局图 /mr的压缩 今日提纲 一.流量汇总排序的实现 1.需求 对日志数据 ...

  3. FusionInsight大数据开发---Spark应用开发

    Spark应用开发 要求: 了解Spark基本原理 搭建Spark开发环境 开发Spark应用程序 调试运行Spark应用程序 YARN资源调度,可以和Hadoop集群无缝对接 Spark适用场景大多 ...

  4. 大数据入门第八天——MapReduce详解(四)本地模式运行与join实例

    一.本地模式调试MR程序 1.准备 参考之前随笔的windows开发说明处:http://www.cnblogs.com/jiangbei/p/8366238.html 2.流程 最重要的是设置Loc ...

  5. 大数据入门第九天——MapReduce详解(六)MR其他补充

    一.自定义in/outputFormat 1.需求 现有一些原始日志需要做增强解析处理,流程: 1. 从原始日志文件中读取数据 2. 根据日志中的一个URL字段到外部知识库中获取信息增强到原始日志 3 ...

  6. 大数据入门第九天——MapReduce详解(五)mapJoin、GroupingComparator与更多MR实例

    一.数据倾斜分析——mapJoin 1.背景 接上一个day的Join算法,我们的解决join的方式是:在reduce端通过pid进行串接,这样的话: --order ,,P0001, ,,P0001 ...

  7. 大数据开发-从cogroup的实现来看join是宽依赖还是窄依赖

    前面一篇文章提到大数据开发-Spark Join原理详解,本文从源码角度来看cogroup 的join实现 1.分析下面的代码 import org.apache.spark.rdd.RDD impo ...

  8. 大数据开发-Spark-拷问灵魂的5个问题

    1.Spark计算依赖内存,如果目前只有10g内存,但是需要将500G的文件排序并输出,需要如何操作? ①.把磁盘上的500G数据分割为100块(chunks),每份5GB.(注意,要留一些系统空间! ...

  9. 详解Kafka: 大数据开发最火的核心技术

    详解Kafka: 大数据开发最火的核心技术   架构师技术联盟 2019-06-10 09:23:51 本文共3268个字,预计阅读需要9分钟. 广告 大数据时代来临,如果你还不知道Kafka那你就真 ...

随机推荐

  1. 【Spring】Spring的事务管理 - 1、Spring事务管理概述(数据库事务、Spring事务管理的核心接口)

    Spring事务管理概述 文章目录 Spring事务管理概述 数据库事务 什么是Spring的事务管理? Spring对事务管理的支持 Spring事务管理的核心接口 Platform Transac ...

  2. Http中的options请求

    引自:https://www.jianshu.com/p/5cf82f092201.https://www.cnblogs.com/mamimi/p/10602722.html 一.options是什 ...

  3. Linux中让终端输入变为非阻塞的三种方法

    介绍 在linux下每打开一个终端,系统自动的就打开了三个文件,它们的文件描述符分别为0,1,2,功能分别是"标准输入"."标准输出"和"标准错误输出 ...

  4. pytest:conftest.py文件

    一.fixture scope 为session 级别是可以跨 .py模块调用的,也就是当我们有多个 .py文件的用例时,如果多个用例只需调用一次fixture,可以将scope='session', ...

  5. 善用tempfile库创建python进程中的临时文件

    技术背景 临时文件在python项目中时常会被使用到,其作用在于随机化的创建不重名的文件,路径一般都是放在Linux系统下的/tmp目录.如果项目中并不需要持久化的存储一个文件,就可以采用临时文件的形 ...

  6. OpenDaylight — YANG

    1. 介绍 YANG 是一种用于为 NETCONF 协议建模数据的语言. YANG 将数据的层次结构建模为一棵树. 2. 节点类型 2.1 leaf 它只有一个特定类型的值,并且没有子节点. YANG ...

  7. Redis 实战 —— 08. 实现自动补全、分布式锁和计数信号量

    自动补全 P109 自动补全在日常业务中随处可见,应该算一种最常见最通用的功能.实际业务场景肯定要包括包含子串的情况,其实这在一定程度上转换成了搜索功能,即包含某个子串的串,且优先展示前缀匹配的串.如 ...

  8. 网络优化之net.ipv4.tcp_tw_recycle和tcp_tw_reuse参数

    网络优化之net.ipv4.tcp_tw_recycle和tcp_tw_reuse参数 - 一个人默默潜行 - 博客园 https://www.cnblogs.com/ppp1314520818/p/ ...

  9. Golang 性能优化实战

    小结: 1. 性能查看工具 pprof,trace 及压测工具 wrk 或其他压测工具的使用要比较了解. 代码逻辑层面的走读非常重要,要尽量避免无效逻辑. 对于 golang 自身库存在缺陷的,可以寻 ...

  10. 线上nginx的一次“no live upstreams while connecting to upstream ”分析

    线上nginx的一次"no live upstreams while connecting to upstream "分析 线上nginx的一次"no live upst ...