|NO.Z.00060|——————————|BigDataEnd|——|Hadoop&MapReduce.V31|——|Hadoop.v31|调优及二次开发|MR调优-shuffle调优|
一、Shuffle调优
~~~ [MR调优-shuffle调优-Map端调优]
~~~ [MR调优-shuffle调优-Combiner]
~~~ [MR调优-shuffle调优-Reduce端调优]
### --- Shuffle调优
~~~ Shuffle阶段是MapReduce性能的关键部分,
~~~ 包括了从MapTaskask将中间数据写到磁盘一直到ReduceTask拷贝数据并最终放到
~~~ Reduce函数的全部过程。这一块Hadoop提供了大量的调优参数。

二、Map阶段
### --- 判断Map内存使用
~~~ 判断Map分配的内存是否够用,可以查看运行完成的job的Counters中(历史服务器),
~~~ 对应的task是否发生过多次GC,以及GC时间占总task运行时间之比。
~~~ 通常,GC时间不应超过task运行时间的10%,
~~~ 即GC time elapsed (ms)/CPU time spent (ms)<10%。

~~~ Map需要的内存还需要随着环形缓冲区的调大而对应调整。可以通过如下参数进行调整。
~~~ mapreduce.map.memory.mb
### --- Ma需要的CPU核数可以通过如
~~~ 下参数调整
mapreduce.map.cpu.vcores

### --- 可以看到内存默认是1G,CPU默认是1核。
~~~ 如果集群资源充足建议调整:
mapreduce.map.memory.mb=3G(默认1G)mapreduce.map.cpu.vcores=1(默认也是1)
### --- 环形缓冲区
~~~ Map方法执行后首先把数据写入环形缓冲区,为什么MR框架选择先写内存而不是直接写磁盘?
~~~ 这样的目的主要是为了减少磁盘i/o
~~~ 环形缓冲默认100M(mapreduce.task.io.sort.mb),
~~~ 当到达80%(mapreduce.map.sort.spill.percent)时就会溢写磁盘。
~~~ 每达到80%都会重写溢写到一个新的文件。
~~~ # 当集群内存资源充足,考虑增大mapreduce.task.io.sort.mb提高溢写的效率,而且会减少中间结果的文件量。
### --- 建议:
~~~ 调整mapreduce.task.io.sort.mb=512M。
~~~ 当文件溢写完后,会对这些文件进行合并,默认每次合并
~~~ 10(mapreduce.task.io.sort.factor)个溢写的文件,建议调整
~~~ mapreduce.task.io.sort.factor=64。这样可以提高合并的并行度,减少合并的次数,降低对磁盘操作的次数。
### --- Combiner
~~~ 在Map阶段,有一个可选过程,将同一个key值的中间结果合并,叫做Combiner。
~~~ (一般将reduce类设置为combiner即可)
~~~ 通过Combine,一般情况下可以显著减少Map输出的中间结果,从而减少shuffle过程的网络带宽占用。
### --- 建议:
~~~ 不影响最终结果的情况下,加上Combiner!!
### --- Copy阶段
~~~ 对Map的中间结果进行压缩,当数据量大时,会显著减少网络传输的数据量,
~~~ 但是也因为多了压缩和解压,带来了更多的CPU消耗。因此需要做好权衡。当任务属于网络瓶颈类型时,压缩Map中间结果效果明显。
~~~ 在实际经验中Hadoop的运行的瓶颈一般都是IO而不是CPU,压缩一般可以10倍的减少IO操作
三、Reduce阶段
### --- Reduce资源
~~~ 每个Reduce资源
mapreduce.reduce.memory.mb=5G(默认1G)
mapreduce.reduce.cpu.vcores=1(默认为1)。
### --- Copy
~~~ ReduceTask在copy的过程中默认使用5(mapreduce.reduce.shuffle.parallelcopies参数控制)
~~~ 个并行度进行复制数据。
~~~ 该值在实际服务器上比较小,建议调整为50-100.
### --- 溢写归并
~~~ Copy过来的数据会先放入内存缓冲区中,然后当使用内存达到一定量的时候spill磁盘。
~~~ 这里的缓冲区大小要比map端的更为灵活,它基于JVM的heap size设置。
~~~ 这个内存大小的控制是通过mapreduce.reduce.shuffle.input.buffer.percent(default 0.7)控制的。
~~~ shuffile在reduce内存中的数据最多使用内存量为:0.7 × maxHeap of reduce task,
~~~ 内存到磁盘merge的启动可以通过mapreduce.reduce.shuffle.merge.percent(default0.66)配置。
~~~ copy完成后,reduce进入归并排序阶段,合并因子默认为10(mapreduce.task.io.sort.factor参数控制),
~~~ 如果map输出很多,则需要合并很多趟,所以可以提高此参数来减少合并次数。
mapreduce.reduce.shuffle.parallelcopies # 复制数据的并行度,默认5;建议调整为50-100
mapreduce.task.io.sort.factor # 一次合并文件个数,默认10,建议调整为64
mapreduce.reduce.shuffle.input.buffer.percent # 在shuffle的复制阶段,分配给Reduce输出缓冲区占堆内存的百分比,默认0.7
mapreduce.reduce.shuffle.merge.percent # Reduce输出缓冲区的阈值,用于启动合并输出和磁盘溢写的过程
Walter Savage Landor:strove with none,for none was worth my strife.Nature I loved and, next to Nature, Art:I warm'd both hands before the fire of life.It sinks, and I am ready to depart
——W.S.Landor
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」