Hadoop的shuffle过程及调优

这篇具有很好参考价值的文章主要介绍了Hadoop的shuffle过程及调优。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

MapReduce 中的Shuffle 发生在 map 输出到 reduce 输入的过程,它的中文解释是 “洗牌”,顾名思义该过程涉及数据的重新分配,主要分为两部分:

  1. map 任务输出的数据分组、排序,写入本地磁盘。
  2. reduce 任务拉取排序。

由于该过程涉及排序、磁盘IO、以及网络IO 等消耗资源和 CPU 比较大的操作,因此该过程是重点优化的一个地方,也是大数据面试中经常会被重点考察的地方。本文力求通俗、简单地将 Shuffle 过程描述清楚。包含 Shuffle 过程的 MapReduce 任务处理流程如下图,图片来自《Hadoop权威指南(第四版)》
Hadoop的shuffle过程及调优
接下来,分别介绍 Shuffle 所涉及的主要操作。

Map 端

map 端输出时,先将数据写入内存中的环形缓冲区,默认大小为 100M,可以通过 mapreduce.task.io.sort.mb 来设置。map 端输出过程如下:

  1. 当缓冲区的内容大小达到阈值(默认 0.8,即缓冲区大小的 80%,可通过 mapreduce.map.sort.spill.percent 设置),便有一个后台线程会将写入缓冲区的内容溢写到磁盘。溢写的过程中 map 任务仍然可以写缓冲区,一旦缓冲区写满,map 任务阻塞,直到后台线程写磁盘结束
  2. 后台线程写磁盘之前会计算输出的 key 的分区(一个分区对应一个 reduce 任务),同一个分区的 key 分在一组并按照 key 排序。最后写到本地磁盘。如果设置 combiner 函数,会在写磁盘之前调用 combiner 函数。combiner 是先将数据聚合,从而减少网络IO,且不会影响 reduce 计算结果的一个操作。
  3. 每一次溢写都会产生一个溢出文件,map 输出结束后会产生多个溢出文件。最终会被合并成一个分区的且有序的文件。这里为什么要合并成 1 个,因为如果 map 输出的数据比较多,产生本地的小文件会太多,影响系统性能。因此需要进行合并,通过 mapreduce.task.io.sort.factor 设置一次可以合并的文件个数,默认为 10
  4. 输出到磁盘的过程中可以设置压缩, 默认不压缩。通过设置 mapreduce.map.output.compress 为 true 开启压缩

以上便是 map 任务输出过程的主要操作,输出到磁盘后,reducer 会通过 http 服务拉取输出文件中属于自己分区的数据。

Reduce 端

reduce 端在 Shuffle 阶段主要涉及复制和排序两个过程。

  1. reduce 端拉取 map 输出数据的过程是复制阶段,对应上图中的 fetch。一个 reduce 任务需要从多个 map 输出复制。因此只要有 map 任务完成,reduce 任务就可以进行复制。复制的过程可以是多线程并发进行,并发的线程个数由 mapreduce.reduce.shuffle.parallelcopies 设置,默认是 5 。
  2. map 任务完成后通过心跳通知 application master,reduce 端会有一个线程定期查询 application master,以获取完成的 map 任务的位置,从而去对应的机器复制数据
  3. reduce 复制的数据先写到 reduce 任务的 JVM 内存,通过 mapreduce.reduce.shuffle.input.buffer.percent 控制可以用的内存比例
    如果复制的数据大小达到内存阈值(通过 mapreduce.reduce.shuffle.merge.percent 控制)或者复制的文件数达到阈值(通过 mapreduce.reduce.merge.inmem.threshold 控制,默认 1000)则将内存的数据合并溢写到磁盘,如果设置了 combine 函数,写磁盘前会调用 combine 函数以减少写入磁盘的数据量
  4. 复制阶段结束后,reduce 将进入排序阶段。如果发生了上面第三步,即产生溢写,那么磁盘可能会有多个溢写文件,此时需要将磁盘文件合并并排序。如果溢写的文件较多,需要多次合并,每次合并的文件数由 mapreduce.task.io.sort.factor 控制。最后一次合并排序的时候不会将数据写到磁盘而直接作为 reduce 任务的输入

以上便是 reduce 任务前的复制、排序阶段。至此,整个 Shuffle 过程就介绍完毕。

参数调优

我们在上面介绍 Shuffle 过程时已经提到了一些参数,这里统一整理并说明一下

Map 端调优参数

参数名 默认值 说明
mapreduce.task.io.sort.mb 100 map 输出是所使用的内存缓冲区大小,单位:MB
mapreduce.map.sort.spill.percent 0.80 map 输出溢写到磁盘的内存阈值
mapreduce.task.io.sort.factor 10 排序文件是一次可以合并的流数
mapreduce.map.output.compress false map 输出是否压缩
mapreduce.map.output.compress.codec org.apache.hadoop.io.compress.DefaultCodec map 输出压缩的编解码器

我们希望在 map 输出阶段能够提供更多的内存空间,以提升性能。因此 map 函数应该尽量少占用内存,以便留出内存用于输出。我们也可以评估 map 输出,通过增大 mapreduce.task.io.sort.mb 值来减少溢写的文件数。

Reduce 端调优参数

参数名 默认值 说明
mapreduce.reduce.shuffle.parallelcopies 5 并发复制的线程数
mapreduce.task.io.sort.factor 10 同 map 端
mapreduce.reduce.shuffle.input.buffer.percent 0.70 Shuffle 的复制阶段,用来存放 map 输出缓冲区占reduce 堆内存的百分比
mapreduce.reduce.shuffle.merge.percent 0.66 map 输出缓冲区的阈值,超过该比例将进行合并和溢写磁盘
mapreduce.reduce.merge.inmem.threshold 1000 阈值,当累积的 map 输出文件数超过该值,进行合并和溢写磁盘,0或者负值意味着改参数无效,合并和溢写只由 mapreduce.reduce.shuffle.merge.percent 控制
mapreduce.reduce.input.buffer.percent 0.0 大于0时,会保留指定比例得内存读Buffer中的数据直接拿给Reduce使用。

默认情况下,reduce 任务开始前所有的 map 输出合并到磁盘,以便为 reducer 提供尽可能多的内存。如果 reducer 需要的内存较少,可以增加此值以最小化磁盘访问次数。
在 reduce 端,进行 reduce 函数前,如果中间数据全部驻留内存可以获得最佳性能,默认情况是不能实现的。如果 reduce 函数内存需求不大,把 mapreduce.reduce.input.buffer.percent 参数设置大一些可以提升性能。

总结

这章里,我们详细介绍了 Shuffle 过程,关注 Shuffle 过程的性能对整个 MR 作业的性能调优至关重要。经过这章的介绍,我们能够掌握 Shuffle 过程的关键技术点,虽然还不算深入。同时,我们介绍了常见的参数以及调优方法,希望能够在实际应用中不断的尝试、总结,写出性能最佳的任务。文章来源地址https://www.toymoban.com/news/detail-488626.html

到了这里,关于Hadoop的shuffle过程及调优的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • d3.shuffle、Fisher–Yates算法以及js 中的slice

    D3.shuffle() 方法用于将数组中的元素随机排序。它使用 Fisher–Yates 洗牌算法,该算法是无偏的,具有最佳的渐近性能(线性时间和常数内存)。 D3.shuffle() 方法的语法如下: 其中: array 是原数组。 start 是开始索引,默认为 0。 end 是结束索引,默认为数组的长度。 如果 end 是

    2024年02月08日
    浏览(37)
  • MySQL性能测试及调优中的死锁处理方法

    以下从死锁检测、死锁避免、死锁解决3个方面来探讨如何对MySQL死锁问题进行性能调优。 死锁检测 通过SQL语句查询锁表相关信息: (1)查询表打开情况 1 (2)查询锁情况列表 1 (3)查询锁等待信息,其中blocking_lock_id是当前事务在等待的事务 1 (4)查询死锁日志 SHOW ENGI

    2024年01月17日
    浏览(36)
  • Hadoop MapReduce 调优参数

    前言: 下列参数基于 hadoop v3.1.3 版本,共三台服务器,配置都为 4 核, 4G 内存。 MapReduce 调优参数详解 这个参数定义了在 Reduce 阶段同时进行的拷贝操作的数量,用于从 Map 任务获取数据,增加此值可以加速 Shuffle 阶段的执行。 默认值: 5 建议配置: 10 定义了在 Reduce 阶段输

    2024年02月10日
    浏览(39)
  • Spark学习笔记【shuffle】

    本文基本上是大数据处理框架Apache Spark设计与实现的Shuffle部分的学习。以及Spark基础知识@Bambrow 上游和下游,不同stage,不同的task之间是如何传递数据的。 ShuffleManager 管理ShuffleWrite和ShuffleRead 分为两个阶段: ShuffleWrite 上游stage输出的分区问题。 ShuffleRead 下游stage从上游获取

    2024年02月03日
    浏览(60)
  • 【Spark精讲】Spark Shuffle详解

    目录 Shuffle概述 Shuffle执行流程 总体流程 中间文件 ShuffledRDD生成 Stage划分 Task划分 Map端写入(Shuffle Write) Reduce端读取(Shuffle Read) Spark Shuffle演变 SortShuffleManager运行机制 普通运行机制 bypass 运行机制 Tungsten Sort Shuffle 运行机制 基于Sort的Shuffle机制的优缺点 Shuffle调优 广播变量 shu

    2024年02月02日
    浏览(47)
  • 【Python基础函数笔记】random.shuffle()

     官方文档:random --- 生成伪随机数 — Python 3.10.11 文档 random.shuffle()用来打乱列表的。

    2024年02月11日
    浏览(79)
  • Spark Shuffle Tracking 原理分析(1)

    如果开启了 ESS,那么 Executor 计算完后,把 shuffle 数据交给 ESS, Executor 没有任务时,可以安全退出,下游任务从 ESS 拉取 shuffle 数据。 1. 背景 如果 Executor 执行了上游的 Shuffle Map Task 并且把 shuffle 数据些到本地。并且现在 Executor 没有 Task 运行,那么此 Executor 是否能销毁? 现状

    2024年04月16日
    浏览(27)
  • Hadoop3教程(三十四):(生产调优篇)MapReduce生产经验汇总

    MR程序执行效率的瓶颈,或者说当你觉得你的MR程序跑的比较慢的时候,可以从以下两点来分析: 计算机性能 节点的CPU、内存、磁盘、网络等,这种属于硬件上的检查; IO操作上的检查 是否发生了数据倾斜?即单一reduce处理了绝大部分数据 Map运行时间过长,导致Reduce一直在

    2024年02月08日
    浏览(53)
  • 大数据课程K6——Spark的Shuffle详解

    文章作者邮箱:yugongshiye@sina.cn              地址:广东惠州 ⚪ 了解Spark的定义特点目的优缺点; ⚪ 掌握Spark的相关参数配置; ⚪ 掌握Hadoop的插件配置; Shuffle,就是洗牌。之所以需要Shuffle,还是因为具有某种共同特征的一类数据需要最终汇聚(aggregate)到一个计算节点

    2024年02月11日
    浏览(38)
  • Spark 提交任务参数设置关于(线程,shuffle,序列化)

    是在使用 Apache Spark 时,为了设置 Java 虚拟机(JVM)的堆栈大小而使用命令行选项。 -Xss 是 Java 虚拟机的一个选项,用于设置线程的堆栈大小。在这个命令行选项中, -Xss6m 表示将线程的堆栈大小设为 6MB。这个选项的作用是为了避免在运行 Spark 任务时出现堆栈溢出的错误。

    2024年02月02日
    浏览(570)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包