MapReduce跑的慢的原因
-
计算机性能
CPU,内存,磁盘健康,网络 -
IO操作优化
(1)数据倾斜
(2)map和reduce数设置不合理
(3)map运行时间太长,导致reduce等待过久
(4)小文件过多
(5)大量的不可分块的超大文件
(6)spill次数过多
(7)merge次数过多
MapReduce优化方法
MapReduce优化方法六个方;
- 数据输入
(1)合并小文件:在执行mr任务前,将小文件进行合并,大量的小文件会产生大量的map任务,增大map任务转载次数,而任务的装载比较耗时,从而导致mr运行较慢
(2)采用CombineTextInputFormat来作为输入,解决输入端大量小文件场景
- Map阶段
(1) 减少一些溢写(spill)次数:通过调整io.sort.mb以及sort.spill.percent参数值,增大触发spill内存上限,减少spill次数,从而减少磁盘IO
(2)减少合并(merge)次数:通过调整io.sort.factor参数,增大merge的文件数目,减少merge次数,从而缩短mr处理时间
(3)在map之后,不影响业务逻辑的前提下,先进行combine处理,减少IO
Reduce阶段
1)合理设置map和Reduce数,两个都不能设置太少,不能太多,太少会导致task等待,延长处理时间,太多会导致map,reduce任务间竞争资源,造成处理超时等错误
2)设置map,reduce共存,通过slowstart.completedmaps参数,使map运行一定程度后,reduce也开始运行,减少reduce的等待时间
3)规避使用reduce:reduce在用于连接数据集的时候会产生大量网络消耗
4)合理设置reduce端buff:默认情况下,数据达到一定的阈值的时候,buffer中的数据会写入磁盘,然后reduce会从磁盘中获取所有的数据,也就是说,buffer和reduce是没有直接关联的,中间多一个写入磁盘和读磁盘的过程,既然有这个弊端,就可以通过参数配置,使得buffer中的一部分数据直接输送到reduce,从而减少IO的销,mapred.job.reduce.input.buffer.percent,默认为 0.0。当值大于0时,会保留指定比例的内存读buffer中的数据直接拿给reduce使用,这样设置buffer需要内存,读取数据需要内存,reduce计算的时候也要内存,所以要根据作业的运行情况进行调整
IO传输:
- 采用数据压缩方式,减少网络IO的时间,安装Snappy和LZO压缩编码器
- 使用SequenceFile二进制文件
数据倾斜问题
(1)数据倾斜
数据频率倾斜 某一个区域的数据量要远远大于其他地区
数据大小倾斜 部分记录的大小远远大于平均值
(2) 如果收集倾斜数据
在reduce方法中加入记录map输出键的详细情况的功能
public static final String MAX_VALUES = "skew.maxvalues";
private int maxValueThreshold;
@Override
public void configure(JobConf job) {
maxValueThreshold = job.getInt(MAX_VALUES, 100);
}
@Override
public void reduce(Text key, Iterator<Text> values,
OutputCollector<Text, Text> output,
Reporter reporter) throws IOException {
int i = 0;
while (values.hasNext()) {
values.next();
i++;
}
if (++i > maxValueThreshold) {
log.info("Received " + i + " values for key " + key);
}
}
(3)减少数据倾斜的方法
方法1:抽样和范围分区
可以通过对原始数据进行抽样得到结果集来预设分区边界值
方法2:自定义分区
基于输出键的背景知识进行自定义分区,例如:如果map输出键的单词来源于一本书,且其中某一个专业词汇较多,那么久可以自定义分区将这些专业词汇发送给固定的一部分reduce实例,而将其他的都发送给剩余的reduce实例
方法3:Combine
使用Conbine可以大量的减少数据倾斜,在可能的情况下,combine的目的就是聚合并精简数据
方法4:采用MapJoin,尽量避免Reduce Join
常用调优参数
1)资源相关参数
(1)以下参数是在用户自己的 mr 应用程序中配置就可以生效(mapred-default.xml)
(2)应该在 yarn 启动之前就配置在服务器的配置文件中才能生效(yarn-default.xml)
(3)shuffle 性能优化的关键参数,应在 yarn 启动之前就配置好(mapred-default.xml)
2)容错相关参数(mapreduce 性能优化)
HDFS小文件优化方法
-
HDFS小文件弊端
HDFS上每一个文件都要在namendoe上建立一个索引.这个索引的大小约150byte这样当小文件较多时,就会产生很多的索引文件,一方面会大量占用namenode的内存使用 -
Sequence file
Sequence file 是由一系列二进制key/value组成,如果key为文件名,value为文件内容 则可以将大批小文件合并成一个大文件,则可以将大批小文件合并成一个大文件 -
CombineFileInputFormat
CombineFileInputFormat 是一种新的inputformat,用于将多个文件合并成一个单独的split,另外,它会考虑数据存储位置 -
开启JVM重用
对于大量小文件Job,可以开启JVM重用,会减少45%运行时间
JVM重用理解:一个map运行一个JVM,重用的话,在一个map在jvm运行完毕后,jvm继续运行其他map
具体设置:mapreduce.job.jvm.numtasks 值在 10-20 之间。