Spark 数据倾斜调优
一、what is a shuffle?
1.1 shuffle简介
一个stage执行完后,下一个stage开始执行的每个task会从上一个stage执行的task所在的节点,通过网络传输获取task需要处理的所有key,然后每个task对相同的key进行算子操作,这个过程就是shuffle过程。
我们常说的shuffle过程之所以慢是因为有大量的磁盘IO以及网络传输操作。spark中负责shuffle的组件主要是ShuffleManager,在spark1.1之前采用的都是HashShuffleManager,在1.1之后开始引入效果更优SortShuffleManager,并在1.2开始默认使用SortShuffleManager。
1.2 HashShuffleManager
我们来看下最初的ShuffleManager:HashShuffleManager中shuffle的读写过程
从上图我们可以看出,Executor中每个core对应的task在shuffle写的时候都会产生和下一个stage包含task数目一样的磁盘文件,也就是说下一个stage包含多少个task(即Reducer),当前stage的task就会产生多少个磁盘文件。那么100个单核的Executor,当前stage有200个task,每个Executor负责执行2个task,下一个stage有100个task,那么一次shuffle write需要产生200*100=20000个磁盘文件。每个buffer(即图中的bucket)的大小默认为32KB(Spark1.1中默认是100KB,可以通过spark.shuffle.file.buffer.kb来设置);在shuffle read阶段每个task从上一个stage中的每一个task中通过网络传输拉取相同key的数据进行聚合等shuffle操作。所以产生的磁盘文件越多,shuffle read的IO操作就越频繁,且大量的buffer将对Executor的存储空间产生巨大的压力。
Spark团队对针对“磁盘文件多”这一弊端进行了优化,优化后的HashShuffleManager的shuffle的读写过程:
从上图我们可以看出,下一个stage的每个task的入度变成了优化前的一半,主要是因为每个core都产生了和下一个stage的task相同数目的磁盘文件,同一core中的不同task复用一批磁盘文件,减少磁盘文件数据,提升shuffle write性能。那么与上面相同环境下,优化后需要产生的磁盘文件数量为Executor数*Executor的core数*下一个stage的task数=100*1*100=10000。可以通过将spark.shuffle.consolidateFiles设置为true来开启consolidate机制,即优化后的HashShuffleManager。
1.3 sortShuffleManager
Spark 1.2 后开始默认使用sortShuffleManager
SortShuffleManager主要改进点是在内存溢写到磁盘文件之前,会根据Partition id以及key对内存数据进行sort排序,然后再分批写入磁盘文件,分批的batch数量大小为1w条,最后将产生的多个磁盘文件merge成一个磁盘文件,并产生一个索引文件,用以标识下游stage中的各个task的数据在文件中的start offset 和 end offset,直观来看,一个task仅产生一个磁盘文件和一个索引文件。产生的磁盘文件少了,但增加了排序的性能开销,如果这部分在你的业务场景下开销大,那么可以选择SortShuffleManager的bypass机制。
在ShuffleManager一路优化的过程中,一个重要优化思想其实就是在减少shuffle过程中产生磁盘文件数量,一个直观的逻辑:磁盘文件少,上下游stage需要进行的磁盘IO操作就相对少了。而磁盘文件过多会带来以下问题:
如果磁盘文件多,进行shuffle操作时需要同时打开的文件数多,大量的文件句柄和写操作分配的临时内存将对内存和GC带来压力,特别是在YARN的模式下,往往Executor分配的内存不足以支持这么大的内存压力;
如果磁盘文件多,那么其所带来的随机读写需要多次磁盘寻道和旋转延迟,比顺序读写的时间多许多倍。
可以通过Spark.shuffle.manager参数来设置使用哪种shuffle manager。
以上我们介绍了what is a shuffle,shuffle write 与 shuffle read的过程,以及为什么shuffle对spark任务性能消耗大,在整体上了解shuffle之后,我们来了解下如何handle shuffle。
二、判断定位
spark web ui 上task的执行时间或分配的数据量,如果一般task执行时间只有几秒,而某些task执行时间是几分钟甚至更久,那这部分task对于的stage就出现了数据倾斜,根据之前的stage的划分方式即可定位哪段代码中的算子导致了数据倾斜。
常见的触发shuffle操作的算子:distinct、groupByKey、reduceByKey、aggregateByKey、join、cogroup、repartition等
三、深究key分布
如果是数据倾斜的数据来源于hive表,那么我们可以分析下spark sql中key的数据分布情况
如果数据来源于中间的RDD,那么可以使用RDD.countByKey()来统计不同key出现的次数
如果数据量大,可以使用采样来分析,比如:
val sampledRDD = shuffleRDD.sample(false, 0.1)
val sampledKeyCounts = sampledRDD.countByKey()
sampledKeyCounts.foreach(println(_))
四、How to fix it?
数据来源于hive表,将导致数据倾斜的shuffle算子前置到**hive ETL(提取、转换和加载)**中,之后的spark任务可反复基于hive ETL后的中间表,保证了spark任务的性能。适用于多次数据计算,且对spark性能要求高的场景。
不是所有的数据都有用,如果filter少数几个数据量大的key不影响数据结果,那在数据预处理的时候可以进行过滤,或者需要动态判定key是否有用,可以在数据计算前对RDD进行sample采样,过滤数据量大的key,这样不仅可以避免数据倾斜,也可以避免相同的代码在某天突然OOM的情况,有可能这一天有某个平时表现正常的key暴增导致OOM。
shuffle算子并行操作,我们知道在shuffle过程中,分布在不同task的相同key的数据会通过网络传输到同一个task进行shuffle计算,这时候一个task可能会处理多种key的数据,比如k1,k2,k3可能都被拉取到某一个task上进行reduce操作,如果k1,k2,k3的数量比较大,我们可以通过提高reduce的并行度来使得k1,k2,k3的数据分别拉取到t1,t2,t3三个task上计算,怎么做呢?如果是RDD的shuffle操作,给shuffle算子传入一个参数即可,比如reduceByKey(600),如果是Spark SQL的shuffle操作,配置一个shuffle参数:spark.sql.shuffle.partitions,该参数表示shuffle read task的并行度,默认200,可根据业务场景进行修改。
key 散列设计再聚合,spark的shuffle操作导致的数据倾斜问题在一定意义上可以类比HBase的热点问题,因此HBase的rowkey的散列设计思想可以套用在聚合类的shuffle操作导致的数据倾斜的场景,怎么做呢?先对key进行hash散列,可以使用随机数,也可以针对key的具体内容进行hash,目的是将原本数据量大的key先hash成k个的key,那么原本必须拉取到一个task上进行shuffle计算的数据可以拉取到k个不同的task上计算,在一定程度上可以缓解单个task处理过多数据导致的数据倾斜,然后再对局部聚合后的key去除hash再聚合。这种key散列设计思想在解决join的shuffle操作广泛使用。
”map join replace “reduce join”,如果join操作是大小表的join,可以考虑将小表广播,首先collect到driver的内存中,为其创建一个broadcase变量,这时候Driver和每个Executor都会保存一份小表的全量数据,再在map操作中自定义join的逻辑,在这个join逻辑里,使用已在内存中的全量的小表数据与大表的每一条数据进行key对比连接,用map join来代替普通的reduce join,可以避免数据倾斜。由于需要在内存中存放全量小表,所以小表数据量在一两G是可取的。
Spark 数据倾斜调优的更多相关文章
- 最详细10招Spark数据倾斜调优
最详细10招Spark数据倾斜调优 数据量大并不可怕,可怕的是数据倾斜 . 数据倾斜发生的现象 绝大多数 task 执行得都非常快,但个别 task 执行极慢. 数据倾斜发生的原理 在进行 shuff ...
- Spark学习之路 (九)SparkCore的调优之数据倾斜调优
摘抄自:https://tech.meituan.com/spark-tuning-pro.html 数据倾斜调优 调优概述 有的时候,我们可能会遇到大数据计算中一个最棘手的问题——数据倾斜,此时Sp ...
- Spark(十)Spark之数据倾斜调优
一 调优概述 有的时候,我们可能会遇到大数据计算中一个最棘手的问题——数据倾斜,此时Spark作业的性能会比期望差很多.数据倾斜调优,就是使用各种技术方案解决不同类型的数据倾斜问题,以保证Spark作 ...
- Spark性能优化:数据倾斜调优
前言 继<Spark性能优化:开发调优篇>和<Spark性能优化:资源调优篇>讲解了每个Spark开发人员都必须熟知的开发调优与资源调优之后,本文作为<Spark性能优化 ...
- Spark学习之路 (九)SparkCore的调优之数据倾斜调优[转]
调优概述 有的时候,我们可能会遇到大数据计算中一个最棘手的问题--数据倾斜,此时Spark作业的性能会比期望差很多.数据倾斜调优,就是使用各种技术方案解决不同类型的数据倾斜问题,以保证Spark作业的 ...
- Spark性能优化--数据倾斜调优与shuffle调优
一.数据倾斜发生的原理 原理:在进行shuffle的时候,必须将各个节点上相同的key拉取到某个节点上的一个task来进行处理,比如按照key进行聚合或join等操作.此时如果某个key对应的数据量特 ...
- Spark面试题(五)——数据倾斜调优
1.数据倾斜 数据倾斜指的是,并行处理的数据集中,某一部分(如Spark或Kafka的一个Partition)的数据显著多于其它部分,从而使得该部分的处理速度成为整个数据集处理的瓶颈. 数据倾斜俩大直 ...
- 【转】数据倾斜是多么痛?spark作业/面试/调优必备秘籍
原博文出自于: http://sanwen.net/a/gqkotbo.html 感谢! 来源:数盟 调优概述 有的时候,我们可能会遇到大数据计算中一个最棘手的问题——数据倾斜,此时Spark作业的性 ...
- 【Spark篇】---Spark调优之代码调优,数据本地化调优,内存调优,SparkShuffle调优,Executor的堆外内存调优
一.前述 Spark中调优大致分为以下几种 ,代码调优,数据本地化,内存调优,SparkShuffle调优,调节Executor的堆外内存. 二.具体 1.代码调优 1.避免创建重复的RDD,尽 ...
随机推荐
- 几种常用的SQL优化工具及方法
转自:http://blog.itpub.net/35489/viewspace-764856/ 1. sql 详细执行计划,主要检查驱动路径,索引是否合适:同一个pl/sql窗口连续执行即可:exp ...
- 扫描二维码的实现(barcode) ---- HTML5+
模块:barcode Barcode模块管理条码扫描,提供常见的条码(二维码及一维码)的扫描识别功能,可调用设备的摄像头对条码图片扫描进行数据输入.通过plus.barcode可获取条码码管理对象. ...
- springMVC各个包下的作用
spring的jar各包作用spring.jar是包含有完整发布的单个jar包,spring.jar中包含除了spring-mock.jar里所包含的内容外其它所有jar包的内容,因为只有在开发环境下 ...
- numpy基础入门
1.Numpy是什么 很简单,Numpy是Python的一个科学计算的库,提供了矩阵运算的功能,其一般与Scipy.matplotlib一起使用.其实,list已经提供了类似于矩阵的表示形式,不过nu ...
- 如何用css给input的placeholder设置颜色
我在做页面的时候遇到过这种情况,在input标签中有默认字,但是设计稿上的颜色和input标签中的placeholder的默认颜色不一致.虽然我们可以在js中写出,但是有点过于麻烦了. 所以我就用cs ...
- POI官网中的例子
官方指南中的例子: http://poi.apache.org/spreadsheet/quick-guide.html#New+Sheet 这一节 Workbook wb = new HSSFWor ...
- 双态运维联盟(BOA)正式成立
3月1日,由联想.新华三.华为等12家IT企业在北京正式达成协议,联合发起成立“双态运维联盟”.中国电子工业标准技术协会.信息技术服务分会数据中心运营管理工作组(DCMG)组长肖建一先生出席了会议. ...
- 双态运维分享之:业务场景驱动的服务型CMDB
最近这几年,国内外CMDB失败的案例比比皆是,成功的寥寥可数,有人质疑CMDB is dead?但各种业务场景表明,当下数据中心运维,CMDB依然是不可或缺的一部分,它承载着运维的基础,掌握运维的命脉 ...
- 获取List、Set、Map等字段的泛型参数
测试类加单元测试方法,运行结果在注释里面: package temp; import org.junit.Test; import java.lang.reflect.Field; import ja ...
- Spark Shuffle(ExternalSorter)
1.Shuffle流程 spark的shuffle过程如下图所示,和mapreduce中的类似,但在spark2.0及之后的版本中只存在SortShuffleManager而将原来的HashShuff ...