MapReduce跑的慢的原因

  1. 计算机性能
    CPU,内存,磁盘健康,网络

  2. IO操作优化

    (1)数据倾斜
    (2)map和reduce数设置不合理
    (3)map运行时间太长,导致reduce等待过久
    (4)小文件过多
    (5)大量的不可分块的超大文件
    (6)spill次数过多
    (7)merge次数过多

MapReduce优化方法

MapReduce优化方法六个方;

  1. 数据输入

(1)合并小文件:在执行mr任务前,将小文件进行合并,大量的小文件会产生大量的map任务,增大map任务转载次数,而任务的装载比较耗时,从而导致mr运行较慢
(2)采用CombineTextInputFormat来作为输入,解决输入端大量小文件场景

  1. 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传输:

  1. 采用数据压缩方式,减少网络IO的时间,安装Snappy和LZO压缩编码器
  2. 使用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)

Hadoop的企业化_Hadoop

(2)应该在 yarn 启动之前就配置在服务器的配置文件中才能生效(yarn-default.xml)

Hadoop的企业化_Hadoop_02

(3)shuffle 性能优化的关键参数,应在 yarn 启动之前就配置好(mapred-default.xml)

Hadoop的企业化_Hadoop学习_03

2)容错相关参数(mapreduce 性能优化)

Hadoop的企业化_Hadoop_04

HDFS小文件优化方法

  1. HDFS小文件弊端
    HDFS上每一个文件都要在namendoe上建立一个索引.这个索引的大小约150byte这样当小文件较多时,就会产生很多的索引文件,一方面会大量占用namenode的内存使用

  2. Sequence file
    Sequence file 是由一系列二进制key/value组成,如果key为文件名,value为文件内容 则可以将大批小文件合并成一个大文件,则可以将大批小文件合并成一个大文件

  3. CombineFileInputFormat
    CombineFileInputFormat 是一种新的inputformat,用于将多个文件合并成一个单独的split,另外,它会考虑数据存储位置

  4. 开启JVM重用
    对于大量小文件Job,可以开启JVM重用,会减少45%运行时间
    JVM重用理解:一个map运行一个JVM,重用的话,在一个map在jvm运行完毕后,jvm继续运行其他map
    具体设置:mapreduce.job.jvm.numtasks 值在 10-20 之间。