生产调优8 MapReduce生产经验(重要)
MapReduce生产经验(重要)
MapRedecu跑的慢的原因
- 计算机本身的性能:CPU、内存是否够用、磁盘速度是否最优、网络带宽是否够用
- I/O操作优化
- 数据倾斜:大量数据发送到某一个reduce,导致该reduce没有结束,而其他reduce快速结束。
- Map运行时间太长,导致Reduce等待过久
- 小文件过多,如果是FileInputFormat对每一个文件进行单独的切片,那么会有大量的MapTask
MapReduce常用调优参数
shuffle的Map阶段
1.自定义分区,减少数据倾斜
分区个数 -> ReduceTask个数
定义类,继承Partitioner接口,重写getPartition方法
2.减少溢写的次数
默认达到80%进行溢写,生成一个文件,减少溢写的次数,减少文件个数,merge次数较少
环形缓冲区大小默认是100M,可以提高到200M
mapreduce.task.io.sort.mb
环形缓冲区溢出的阈值,默认80%溢写,可以提高到90%
mapreduce.map.sot.spill.perecent
3.增加每次Merge合并的文件个数
mapreduce.task.io.sort.factor
默认归并的文件数为10,可以提高到20
前提是内存足够用,因为merge的过程把数据加载到内存进行排序
4.在不影响业务结果的前提条件下可以提前采用Combiner
提前对(a,1)(a,1) 进行合并成(a,2),帮助MapReduce先处理一点,提高效率
job.setCombinerClass(xxxReducer.class);
5.为了减少磁盘IO,可以采用Snapy或LZO压缩
map阶段的数据写入磁盘,等待ruduce端来拉取,拉取的过程需要走网络,为了减少网络上的数据传送,可以采用Snapy或LZO压缩
conf.setBoolean("mapreduce.map.output.compress", true);
conf.setClass("mapreduce.map.output.compress.codec",SnappyCodec.class,CompressionCodec.class)
6.调整MapTask内存
mapreduce.map.memory.mb
默认MapTask内存上线1024MB
可以根据 128M数据 - 1G内存处理 原则提高该内存
mapreduce.map.java.opts
控制MapTask堆内存大小,这两个参数的值需要一致
如果内存不足,报错:java.lang.OutOfMemoryError,可能是这个参数没有调整。
7.mapreduce.map.cpu.vcores
默认MapTask的CPU核数1,如果计算密集型任务可以增加CPU核数
8.异常重试
如果MapTask运行失败之后,有重试的机制。每个MapTask最大重试次数4,如果重试次数超过该值,则认为MapTask运行失败。
根据机器性能适当提高mapreduce.map.maxattempts
服务器差适当提高,服务器好适当减少
shuffle的Reduce阶段
1.mapreduce.reduce.shuffle.parallelcopies
每个Reduce去Map中拉取数据,一次从几个Map中拉取数据。
默认5个Map,可以提高到10。
2.mapreduce.reduce.shuffle.input.buffer.percent
Buffer大小占Reduce可用内存的比例
默认是总内存的0.7,可以提高到0.8
3.mepreduce.reduce.shuffle.merge.percent
Buffer中的数据达到多少比例开始写入磁盘进行归并排序
默认是0.66,可以提高到0.72
4.mapreduce.reduce.memory.mb
默认一个?ReduceTask内存上限1024MB
根据128M数据 -> 1G内存原则 可以适当提高内存到4-6G
mapreduce.reduce.java.opts
控制ReduceTask堆内存大小,这两个参数的值需要一致
如果内存不足,报错:java.lang.OutOfMemoryError,可能是这个参数没有调整。
5.mapreduce.reduce.cpu.vcores
默认MapTask的CPU核数1,可以提高到2-4个
6.mapreduce.reduce.maxattempts
每个Reduce Task最大重试次数,一旦重试次数超过该值,则任务Map Task运行失败,默认值4
7.mapreduce.job.reduce.slowstart.completedmaps
当多少比例(占所有MapTask)的MapTask完成后可以开启ReduceTask,默认是0.05
8.mapreduce.task.timeout
如果一个Task在一定时间内不会读取新的数据, 也没有输出数据, 则认为该Task处于Block状态,可能是卡住了, 也许永远会卡住, 为了防止因为用户程序永远Block住不退出, 则强制设置了一个该超时时间(单位毫秒) ,默认是600000( 10分钟)。如果你的程序对每条输入数据的处理时间过长, 建议将该参数调大。
9.如果可以不用Reduce, 尽量不用
有reduce就有shuffle,有shuffle会有分区、排序、合并、拉取过程
MapReduce数据倾斜问题(MapReduce写的很少了)
所有的计算引擎类框架都会存在数据倾斜的问题。
通常数据倾斜发生在Reduce阶段,其他ReduceTask结束,有一个ReduceTask由于需要处理的数据过多还没有结束。
较少数据倾斜的办法
1.首先检查是否空值过多造成的数据倾斜,尤其注意key是否有大量的空
可以直接过滤掉空值
如果想保留空值,就自定义分区,将空值加随机数打散。最后再二次聚合
2.能在map阶段提前处理,最好现在Map阶段处理,如Combiner,MapJoin
3.设置多个reduce个数