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 调优相关推荐

  1. Spark shuffle调优

    Spark shuffle是什么 Shuffle在Spark中即是把父RDD中的KV对按照Key重新分区,从而得到一个新的RDD.也就是说原本同属于父RDD同一个分区的数据需要进入到子RDD的不同的分 ...

  2. 一文搞定MySQL性能调优

    公众号回复关键词获取免费学习资料,加入前后端技术交流群和副业群.新建立的副业Q群:735764906. 数据库的操作越来越成为整个应用的性能瓶颈,这对于Web应用尤其明显.关于数据库的性能,这并不只是 ...

  3. 32查运行内存的map文件_Spark Shuffle调优之调节map端内存缓冲与reduce端内存占比

    本文首先介绍Spark中的两个配置参数: spark.shuffle.file.buffer map端内存缓冲 spark.shuffle.memoryFraction reduce端内存占比 很多博 ...

  4. 大数据技术之_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. ...

  5. spark调优(一)-开发调优,数据倾斜,shuffle调优

    主要分为开发调优.资源调优.数据倾斜调优.shuffle调优几个部分. 开发调优和资源调优是所有Spark作业都需要注意和遵循的一些基本原则,是高性能Spark作业的基础:数据倾斜调优,主要讲解了一套 ...

  6. Spark性能优化:Shuffle调优篇

    Spark性能优化:Shuffle调优篇 一.调优概述 大多数Spark作业的性能主要就是消耗在了shuffle环节,因为该环节包含了大量的磁盘IO.序列化.网络数据传输等操作.因此,如果要让作业的性 ...

  7. Spark性能优化之-shuffle调优

    文章目录 概述 ShuffleManager发展概述 HashShuffleManager运行原理 未经优化的HashShuffleManager 优化后的HashShuffleManager Sor ...

  8. Spark调优 shuffle调优

    参考:Spark性能调优(2) https://blog.csdn.net/qq_21383435/article/details/77720087

  9. 一文搞清楚 Spark RDD到底是什么?

    阅读文本大概需要 5 分钟. 以下内容,部分参考网络资料,也有自己的理解, 图片 99% 为自己制作.如有错误,欢迎留言指出,一起交流. 1简介 Apache Spark 是专为大规模数据处理而设计的 ...

最新文章

  1. Web漏洞扫描(四:知识点及错误总结)
  2. AOP之PostSharp2-OnMethodBoundaryAspect
  3. 执行python文件报错SyntaxError: Non-ASCII character '\xe8' in file, but no encoding declared
  4. 【kernel 中内存分配那点事】
  5. linux命令行使用for循环,小弟我使用过的Linux命令之for - Bash中的For循环
  6. JavaScript:document.execCommand()的用法
  7. 为什么销量总是做不好预测?或许你只差这一份强化资料包
  8. 爬虫笔记11Scrapyyield具体使用
  9. 第4代白盒測试方法介绍--理论篇
  10. java类验证和装载顺序_Java类加载机制实现流程及原理详解
  11. java多线程-线程创建
  12. atom配置python环境_Python编程:用VScode配置Python开发环境
  13. element ui实现动态显示textarea剩余字数
  14. JavaScript:异步执行机制
  15. 再学 GDI+[36]: TGPPen - SetLineCap
  16. 关于睡眠分期中人工判读的一些个人总结
  17. [OS X軟件] 我一直在用的 司机会看的那种 免费资源又多
  18. kero入门学习总结
  19. 前端JSON格式化显示
  20. 一级域名怎么申请二级域名?

热门文章

  1. 一步一步学ROP之linux_x64篇
  2. [Matlab]求解线性方程组
  3. 部署FIM 2010 R2—1先决条件准备
  4. 重新想象 Windows 8.1 Store Apps (85) - 警报通知(闹钟), Tile 的新特性
  5. Lua程序设计--全局变量
  6. 使用Telnet命令收发E-mail
  7. 使用solrj和EasyNet.Solr进行原子更新
  8. [转载](热议)“我不伟大”,但可以让善良“春暖花开”
  9. Dotnet中Socket网络通信
  10. WinAPI: PolylineTo - 绘制一组连续线段(更新当前位置)