shuffle概览

一个spark的RDD有一组固定的分区组成,每个分区有一系列的记录组成。对于由窄依赖变换(例如map和filter)返回的RDD,会延续父RDD的分区信息,以pipeline的形式计算。每个对象仅依赖于父RDD中的单个对象。诸如coalesce之类的操作可能导致任务处理多个输入分区,但转换仍然被认为是窄依赖的,因为一个父RDD的分区只会被一个子RDD分区继承。

Spark还支持宽依赖的转换,例如groupByKey和reduceByKey。在这些依赖项中,计算单个分区中的记录所需的数据可以来自于父数据集的许多分区中。要执行这些转换,具有相同key的所有元组必须最终位于同一分区中,由同一任务处理。为了满足这一要求,Spark产生一个shuffle,它在集群内部传输数据,并产生一个带有一组新分区的新stage。

可以看下面的代码片段:


上面的代码片段只有一个action操作,count,从输入textfile到action经过了三个转换操作。这段代码只会在一个stage中运行,因为,三个转换操作没有shuffle,也即是三个转换操作的每个分区都是只依赖于它的父RDD的单个分区。

但是,下面的单词统计就跟上面有很大区别:


这段代码里有两个reducebykey操作,三个stage。

下面图更复杂,因为有一个join操作:

粉框圈住的就是整个DAG的stage划分。

在每个stage的边界,父stage的task会将数据写入磁盘,子stage的task会将数据通过网络读取。由于它们会导致很高的磁盘和网络IO,所以shuffle代价相当高,应该尽量避免。父stage的数据分区往往和子stage的分区数不同。触发shuffle的操作算子往往可以指定分区数的,也即是numPartitions代表下个stage会有多少个分区。就像mr任务中reducer的数据是非常重要的一个参数一样,shuffle的时候指定分区数也将在很大程度上决定一个应用程序的性能。

优化shuffle

通常情况可以选择使用产生相同结果的action和transform相互替换。但是并不是产生相同结果的算子就会有相同的性能。通常避免常见的陷阱并选择正确的算子可以显著提高应用程序的性能。

当选择转换操作的时候,应最小化shuffle次数和shuffle的数据量。shuffle是非常消耗性能的操作。所有的shuffle数据都会被写入磁盘,然后通过网络传输。repartition , join, cogroup, 和 ?*By 或者 *ByKey 类型的操作都会产生shuffle。我们可以对一下几个操作算子进行优化:

1. groupByKey某些情况下可以被reducebykey代替。

2. reduceByKey某些情况下可以被 aggregatebykey代替。

3. flatMap-join-groupBy某些情况下可以被cgroup代替。

具体细节,知识星球球友可以点击阅读原文进入知识星球阅读。

no shuffle

在某些情况下,前面描述的转换操作不会导致shuffle。当先前的转换操作已经使用了和shuffle相同的分区器分区数据的时候,spark就不会产生shuffle。

举个例子:


由于使用redcuebykey的时候没有指定分区器,所以都是使用的默认分区器,会导致rdd1和rdd2都采用的是hash分区器。两个reducebykey操作会产生两个shuffle过程。如果,数据集有相同的分区数,执行join操作的时候就不需要进行额外的shuffle。由于数据集的分区相同,因此rdd1的任何单个分区中的key集合只能出现在rdd2的单个分区中。 因此,rdd3的任何单个输出分区的内容仅取决于rdd1中单个分区的内容和rdd2中的单个分区,并且不需要第三个shuffle。

例如,如果someRdd有四个分区,someOtherRdd有两个分区,而reduceByKeys都使用三个分区,运行的任务集如下所示:

如果rdd1和rdd2使用不同的分区器或者相同的分区器不同的分区数,仅仅一个数据集在join的过程中需要重新shuffle

在join的过程中为了避免shuffle,可以使用广播变量。当executor内存可以存储数据集,在driver端可以将其加载到一个hash表中,然后广播到executor。然后,map转换可以引用哈希表来执行查找。

增加shuffle

有时候需要打破最小化shuffle次数的规则。

当增加并行度的时候,额外的shuffle是有利的。例如,数据中有一些文件是不可分割的,那么该大文件对应的分区就会有大量的记录,而不是说将数据分散到尽可能多的分区内部来使用所有已经申请cpu。在这种情况下,使用reparition重新产生更多的分区数,以满足后面转换算子所需的并行度,这会提升很大性能。

使用reduce和aggregate操作将数据聚合到driver端,也是修改区数的很好的例子。

在对大量分区执行聚合的时候,在driver的单线程中聚合会成为瓶颈。要减driver的负载,雅思报名条件可以首先使用reducebykey或者aggregatebykey执行一轮分布式聚合,同时将结果数据集分区数减少。实际思路是首先在每个分区内部进行初步聚合,同时减少分区数,然后再将聚合的结果发到driver端实现最终聚合。典型的操作是treeReduce?和?treeAggregate。

当聚合已经按照key进行分组时,此方法特别适用。例如,假如一个程序计算语料库中每个单词出现的次数,并将结果使用map返回到driver。一种方法是可以使用聚合操作完成在每个分区计算局部map,然后在driver中合并map。可以用aggregateByKey以完全分布的方式进行统计,然后简单的用collectAsMap将结果返回到driver。

更多spark技巧,大数据技巧,欢迎点击阅读原文加入知识星球

推荐阅读:

经验|如何设置Spark资源

戳破 | hive on spark
调优点


文章来源:https://blog.csdn.net/rlnLo2pNEfx9c/article/details/81976622

不可不知的spark shuffle的更多相关文章

  1. Spark Shuffle原理、Shuffle操作问题解决和参数调优

    摘要: 1 shuffle原理 1.1 mapreduce的shuffle原理 1.1.1 map task端操作 1.1.2 reduce task端操作 1.2 spark现在的SortShuff ...

  2. spark shuffle 相关细节整理

    1.Shuffle Write 和Shuffle Read具体发生在哪里 2.哪里用到了Partitioner 3.何为mapSideCombine 4.何时进行排序 之前已经看过spark shuf ...

  3. Spark Shuffle数据处理过程与部分调优(源码阅读七)

    shuffle...相当重要,为什么咩,因为shuffle的性能优劣直接决定了整个计算引擎的性能和吞吐量.相比于Hadoop的MapReduce,可以看到Spark提供多种计算结果处理方式,对shuf ...

  4. Spark shuffle详细过程

    有许多场景下,我们需要进行跨服务器的数据整合,比如两个表之间,通过Id进行join操作,你必须确保所有具有相同id的数据整合到相同的块文件中.那么我们先说一下mapreduce的shuffle过程. ...

  5. MapReduce Shuffle原理 与 Spark Shuffle原理

    MapReduce的Shuffle过程介绍 Shuffle的本义是洗牌.混洗,把一组有一定规则的数据尽量转换成一组无规则的数据,越随机越好.MapReduce中的Shuffle更像是洗牌的逆过程,把一 ...

  6. Spark Shuffle实现

    Apache Spark探秘:Spark Shuffle实现 http://dongxicheng.org/framework-on-yarn/apache-spark-shuffle-details ...

  7. Spark Shuffle模块——Suffle Read过程分析

    在阅读本文之前.请先阅读Spark Sort Based Shuffle内存分析 Spark Shuffle Read调用栈例如以下: 1. org.apache.spark.rdd.Shuffled ...

  8. [Spark性能调优] 第四章 : Spark Shuffle 中 JVM 内存使用及配置内幕详情

    本课主题 JVM 內存使用架构剖析 Spark 1.6.x 和 Spark 2.x 的 JVM 剖析 Spark 1.6.x 以前 on Yarn 计算内存使用案例 Spark Unified Mem ...

  9. spark shuffle

    Spark Shuffle 1. Shuffle相关 当Map的输出结果要被Reduce使用时,输出结果需要按key哈希,并且分发到每一个Reducer上去,这个过程就是shuffle.由于shuff ...

随机推荐

  1. static在c\c++中的作用(翁恺c++公开课[28-29]学习笔记)

    static相对来说是一个较复杂的修饰符,c++中的static在c的基础之上又包含了static在类中的应用(也就是说多了static的成员变量和static的成员函数):c\c++中静态变量.对象 ...

  2. 建小程序 - 报Error: EPERM : operation not permitted, scandir mac下改变一个目录的访问权限

    问题:用微信开发者工具,建一个小程序,报错(见图1): 建小程序 - 报Error: EPERM : operation not permitted, scandir 解决: 1.打开终端 2.cd ...

  3. Using Watch Mode

    官方文档地址:https://webpack.js.org/guides/development/#using-watch-mode You can instruct webpack to " ...

  4. Java学习第一周心得体会

    一周的学习很快就过去了,说说我个人的总结吧! 下面几个是我觉得需要牢牢记住的 1.Java的执行机制:先编译.再解释 2.变量以及基本数据类型 3.强类型编程语言:要求变量的类型与值的类型要一致 4. ...

  5. Write-up-CH4INRULZ_v1.0.1

    关于 下载地址:点我 哔哩哔哩:哔哩哔哩 信息收集 网卡:vboxnet0,192.168.56.1/24,Nmap扫存活主机发现IP为192.168.56.101 ➜ ~ nmap -sn 192. ...

  6. 揭秘autoit3的运行机制和反编译原理

    今天发这个帖子的目的在于和论坛里面的朋友交流一下学习心得,主要内容是围绕着autoit3的编译原理.先开门见山的说一下结果,我不知道如何反编译au3,但相信论坛有很多高手,能解开我心中的疑团.我没有想 ...

  7. 如何在cmd中连接数据库

    数据库连接时遇到的问题 : https://www.cnblogs.com/xyzdw/archive/2011/08/11/2135227.htmlping +ip地址: 查看本机ip:ipconf ...

  8. eclipse中maven web项目部署时缺少classes文件或者resources文件

    写这篇博客的原因 问题描述 昨天发现eclipse中maven web项目部署时缺少classes文件或者resources文件 本来以为是很常见的原因, 依次检查"Java Build P ...

  9. Docker 镜像文件的导入和导出

    使用save命令 保存镜像 docker save -o name_by_you.tar exist_images 将文件copy到另一台机器 使用load命令将镜像文件保存到本地仓库 docker ...

  10. idea2019 jsp页面加载不到静态文件原因No mapping found for HTTP request with URI

    最近在使用idea2019 学习ssm,但是发现我在项目引用的静态文件怎么都无法加载出来,找了很久才解决~~ 给上目录结构图: 第一种:使用 ${pageContext.request.context ...