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,尽 ...
随机推荐
- Java实现远程服务生产与消费(RPC)的4种方法-RMI,WebService,HttpClient,RestTemplate
目录 一. 通过rmi实现远程服务的生产与消费 远程服务提供者实现. 创建rmi-provider项目(Maven) 远程服务消费者实现 创建rmi-consumer项目 二. 通过WebServic ...
- 170807、intellij idea maven集成lombok实例
简介: lombok 通过简单注解方式简化java代码.(如消除实体对象的get/setter方法.日志对象声明等...) 安装步骤: 1.选择支持注解处理:Settings-->Build-- ...
- 170522、Linux 平台通过 nginx 和 vsftpd 构建图片服务器
Nginx WEB 服务器 Nginx 是一个高性能的 HTTP 和 反向代理 服务器,也是一个 IMAP/POP3/SMTP 代理服务器. Nginx 是由 Igor Sysoev 为俄罗斯访问量第 ...
- angular中对象与字符串之间的转换
1.angular 里 字符串与对象互转 angular.toJson();将字符串转成对象 angular.forJson(); 将字符串转成对象 2.angular 循环 <scr ...
- 南京网络赛J-Sum【数论】
A square-free integer is an integer which is indivisible by any square number except 11. For example ...
- teamviewer and openconnect-gp (globalprotect) in ubuntu
wget https://download.teamviewer.com/download/teamviewer_i386.deb sudo dpkg -i teamviewer_i386.deb a ...
- 转!idea启动后发现tomcat前面出现红色或是灰色的问号
原博文地址:https://blog.csdn.net/z_zhy/article/details/83068168 直接在idea里 点击File------settings,在搜索框直接搜tomc ...
- Expedition---poj2431(优先队列-堆的实现)
题目链接:http://poj.org/problem?id=2431 题意:一辆卡车需要行驶 L 距离,车上油的含量为 P,在行驶的过程中有 n 个加油站 每个加油站到终点的距离是ai,每个加油站最 ...
- Python开发【模块】:matplotlib 绘制折线图
matplotlib 1.安装matplotlib ① linux系统安装 # 安装matplotlib模块 $ sudo apt-get install python3-matplotlib # 如 ...
- 山寨HTML5API classList类
preface 认为自己去写一些类,你真的会找到自己不足的地方.事实上厉害不是你实现一个类.而是你怎样去设计一个类,能让开发人员更加easy操作. 对于这个操作样式,能够通过javascript訪问s ...