一文搞清楚 Spark shuffle 调优
Spark shuffle 调优
Spark 基于内存进行计算,擅长迭代计算,流式处理,但也会发生shuffle 过程。shuffle 的优化,以及避免产生 shuffle 会给程序提高更好的性能。因为 shuffle 的性能优劣直接决定了整个计算引擎的性能和吞吐量。
下图是官方的说明,1.2 版本之后默认是使用 sort shuffle 。这样会更加高效得利用内存。之前版本默认是 hash shuffle。
SortShuffleManager 的运行机制主要分成两种,一种是普通运行机制,另一种是 bypass 运行机制。当 shuffle reduce task 的数量小于等于bypassMergeThreshold 参数的值时(默认为200),就会启用bypass机制。
我们看下面,图 1-1 是 spark shuffle 过程的普通机制。
图 1-1 sort shuffle 普通机制
看图说话,map task 的计算结果会写入一个内存数据结构中,这个数据结构根据算子,如使用 reduceByKey 这类聚合算子的话,这个内存结构是 Map, 一边通过 Map聚合,一边写入内存;如是使用 join 这类普通算子的话,这个内存结构是 Array,直接写入内存。这个内存结构默认大小是 5 M。
在 shuffle 的时候会有一个定时器,不定期的去估算这个内存结构的大小,当内存结构中的数据超过 5 M 时,比如现在内存结构中的数据是 5.01 M 那么它会申请 5.01*2-5 = 5.02 M 的内存给内存结构,如果成功不会发生溢写,不成功则会发生溢写。
在溢写之前,会根据 key 对内存结构的数据进行排序,然后分批写入磁盘。每一批默认是 10000 条数据。也就是排序好的数据会以每批1 w 条数据的形式写入磁盘。写入磁盘时,由 Java 的 BufferedOutputStream 来实现的,作为缓冲流,现将数据写入缓冲区,等待缓冲区满了再溢出到磁盘,这样减少了磁盘的 IO ,提高了写的性能。
task 完成会后,会将所有的磁盘文件进行一次 Merge 成为一个磁盘文件,所以一个 task 只对应一个磁盘文件,但是还要为下游的 stage 提供数据,所以还要有一个索引文件,其中标识了下游的各个 task 的数据在磁盘文件中的 start offset 和 end offset。
上面提到了,下游的 stage 需要去寻找上一个 stage 产生的数据,也就是所谓的 shuffle 文件寻址。可以看我这篇文章:Spark 的 shuffle 文件寻址流程
bypass 机制,先来看一张流程图 1-2,与上面的普通机制进行对比。
图 1-2 bypass 机制
前面也提到了,bypass 的触发条件是 shuffle reduce task 的数量小于我们设置的 bypassMergeThreshoold 参数。(默认是 200)
通过对比普通机制,可以看出 bypass 机制不会进行排序的过程。shuffle write 过程不会对数据进行排序,这样的话,就节省了这部分的性能开销。
大多数 Spark 作业的性能主要就是消耗在了 shuffle 环节,因为该环节包含了大量的磁盘IO、序列化、网络数据传输等操作。
因此,如果要让作业的性能更上一层楼,就有必要对shuffle过程进行调优。
注意,影响一个Spark作业性能的因素,主要还是代码开发、资源参数以及数据倾斜,shuffle调优只能在整个Spark的性能调优中占到一小部分而已。
后续的文章将会依次从代码开发、资源参数、数据倾斜方面展开。本文只讲解 shuffle 参数的调优。
**
spark.shuffle.file.buffer
参数:默认是 32 k。
说明:表示写入磁盘文件之前缓冲区的大小。
建议:如果资源充足,可以适当按倍数增加,比如 64 k, 从而减少 shuffle write 过程中溢写到磁盘文件的系数,减少磁盘 IO 次数,进而提升性能。1-5%
spark.reducer.maxSizeInFlight
参数:默认是 48 M。
说明:表示 shuffle read 过程拉取数据的 buffer 大小。
建议:如果资源充足,可以适当按倍数增加,比如 96 M, 从而减少拉取次数,减少网络传输的次数,进而提升性能。1-5%
spark.shuffle.io.maxRetries
参数:默认是 3。
说明:表示拉取数据的时候,执行失败重试的时间间隔。
建议:如果一个作业的 shuffle 过程特别耗时,可以加大该参数,比如 60 次,以避免由于 JVM 的 full gc 或者网络原因造成数据拉取失败。
spark.shuffle.io.retryWait
参数:默认是 5 s。
说明:表示拉取数据的时候,重试的最大时长。如果超过这个次数还没有拉取成功,这个任务就会失败。
建议:建议加大间隔时长(比如60s),以增加shuffle操作的稳定性。
spark.shuffle.manager
参数:默认是 sort。
说明:用于设置 ShuffleManager 的类型。
建议:如果你的业务逻辑中需要该排序机制的话,则使用默认的SortShuffleManager就可以;而如果你的业务逻辑不需要对数据进行排序,那么建议通过bypass机制或优化的HashShuffleManager来避免排序操作,同时提供较好的磁盘读写性能。
spark.shuffle.sort.bypassMergeThreshold
参数:默认是 200。
说明:用于设置ShuffleManager的类型。
建议:如果你的业务逻辑中需要该排序机制的话,则使用默认的SortShuffleManager就可以;而如果你的业务逻辑不需要对数据进行排序,那么建议通过bypass机制或优化的HashShuffleManager来避免排序操作,同时提供较好的磁盘读写性能。
spark.shuffle.consolidateFiles
参数:默认是 false。
说明:如果使用 HashShuffleManager,该参数有效。如果设置为true,那么就会开启 consolidate 机制,会大幅度合并 shuffle write 的输出文件,对于shuffle read task数量特别多的情况下,这种方法可以极大地减少磁盘IO开销,提升性能。
建议:如果的确不需要SortShuffleManager的排序机制,那么除了使用bypass机制,还可以尝试将spark.shffle.manager参数手动指定为hash,使用HashShuffleManager,同时开启consolidate机制。在实践中尝试过,发现其性能比开启了bypass机制的SortShuffleManager要高出10%~30%。
更多参数,官方上都有说明:
**
注意,影响一个Spark作业性能的因素,主要还有代码开发、资源参数以及数据倾斜,shuffle调优只能在整个Spark的性能调优中占到一小部分而已。可以关注我后续的文章。
如果对您有帮助,欢迎点好看、关注、转发。
一文搞清楚 Spark shuffle 调优相关推荐
- Spark shuffle调优
Spark shuffle是什么 Shuffle在Spark中即是把父RDD中的KV对按照Key重新分区,从而得到一个新的RDD.也就是说原本同属于父RDD同一个分区的数据需要进入到子RDD的不同的分 ...
- 一文搞定MySQL性能调优
公众号回复关键词获取免费学习资料,加入前后端技术交流群和副业群.新建立的副业Q群:735764906. 数据库的操作越来越成为整个应用的性能瓶颈,这对于Web应用尤其明显.关于数据库的性能,这并不只是 ...
- 32查运行内存的map文件_Spark Shuffle调优之调节map端内存缓冲与reduce端内存占比
本文首先介绍Spark中的两个配置参数: spark.shuffle.file.buffer map端内存缓冲 spark.shuffle.memoryFraction reduce端内存占比 很多博 ...
- 大数据技术之_19_Spark学习_07_Spark 性能调优 + 数据倾斜调优 + 运行资源调优 + 程序开发调优 + Shuffle 调优 + GC 调优 + Spark 企业应用案例
大数据技术之_19_Spark学习_07 第1章 Spark 性能优化 1.1 调优基本原则 1.1.1 基本概念和原则 1.1.2 性能监控方式 1.1.3 调优要点 1.2 数据倾斜优化 1.2. ...
- spark调优(一)-开发调优,数据倾斜,shuffle调优
主要分为开发调优.资源调优.数据倾斜调优.shuffle调优几个部分. 开发调优和资源调优是所有Spark作业都需要注意和遵循的一些基本原则,是高性能Spark作业的基础:数据倾斜调优,主要讲解了一套 ...
- Spark性能优化:Shuffle调优篇
Spark性能优化:Shuffle调优篇 一.调优概述 大多数Spark作业的性能主要就是消耗在了shuffle环节,因为该环节包含了大量的磁盘IO.序列化.网络数据传输等操作.因此,如果要让作业的性 ...
- Spark性能优化之-shuffle调优
文章目录 概述 ShuffleManager发展概述 HashShuffleManager运行原理 未经优化的HashShuffleManager 优化后的HashShuffleManager Sor ...
- Spark调优 shuffle调优
参考:Spark性能调优(2) https://blog.csdn.net/qq_21383435/article/details/77720087
- 一文搞清楚 Spark RDD到底是什么?
阅读文本大概需要 5 分钟. 以下内容,部分参考网络资料,也有自己的理解, 图片 99% 为自己制作.如有错误,欢迎留言指出,一起交流. 1简介 Apache Spark 是专为大规模数据处理而设计的 ...
最新文章
- Web漏洞扫描(四:知识点及错误总结)
- AOP之PostSharp2-OnMethodBoundaryAspect
- 执行python文件报错SyntaxError: Non-ASCII character '\xe8' in file, but no encoding declared
- 【kernel 中内存分配那点事】
- linux命令行使用for循环,小弟我使用过的Linux命令之for - Bash中的For循环
- JavaScript:document.execCommand()的用法
- 为什么销量总是做不好预测?或许你只差这一份强化资料包
- 爬虫笔记11Scrapyyield具体使用
- 第4代白盒測试方法介绍--理论篇
- java类验证和装载顺序_Java类加载机制实现流程及原理详解
- java多线程-线程创建
- atom配置python环境_Python编程:用VScode配置Python开发环境
- element ui实现动态显示textarea剩余字数
- JavaScript:异步执行机制
- 再学 GDI+[36]: TGPPen - SetLineCap
- 关于睡眠分期中人工判读的一些个人总结
- [OS X軟件] 我一直在用的 司机会看的那种 免费资源又多
- kero入门学习总结
- 前端JSON格式化显示
- 一级域名怎么申请二级域名?
热门文章
- 一步一步学ROP之linux_x64篇
- [Matlab]求解线性方程组
- 部署FIM 2010 R2—1先决条件准备
- 重新想象 Windows 8.1 Store Apps (85) - 警报通知(闹钟), Tile 的新特性
- Lua程序设计--全局变量
- 使用Telnet命令收发E-mail
- 使用solrj和EasyNet.Solr进行原子更新
- [转载](热议)“我不伟大”,但可以让善良“春暖花开”
- Dotnet中Socket网络通信
- WinAPI: PolylineTo - 绘制一组连续线段(更新当前位置)