Hadoop 企业级优化

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/hfweather/article/details/82595395

一、MapReduce跑得慢的原因

MapReduce的瓶颈有一下两点:

1、计算机硬件方面

CPU、内存、网络、硬盘等。

2、I/O方面

1、数据倾斜的问题

2、map和reduce设置的个数不合理

3、spill溢写设置的不合理,导致溢写个数过多

4、merge归并文件个数设置不合理,导致归并个数过多

5、map运行的时间过长,导致reduce等待时间太久

6、小文件太多

7、大量的不可分块的超大文件

二、MapReduce的优化方法

MapReduce的优化方法主要从六个方面考虑:数据输入、map阶段、reduce阶段、I/O传输、数据倾斜和系统参数配置。

1、数据输入

a、小文件合并:在执行mr任务前,将大量小文件数据进行合并处理,如果大量小文件输入会导致map任务装载次数增大,map每次装载是很耗时的,所以导致mr运行慢。

b、使用CombineTextInputFormat作为输入,来解决大量小文件的问题。

2、map阶段

a、减少spill(溢写)次数:通过设置 io.sort.mb 及 sort.spill.percent来增大触发spill的内存上限值,从而spill溢写的次数,减少磁盘I/O。

b、减少merge(合并)次数:通过设置 io.sort.factor 参数来增大merge文件上限值,减少merge合并文件的次数,从而增加mr的执行效率。

c、在map之后,在不影响业务的情况下,可以使用combine处理,从而减少I/O传输。

3、reduce阶段

a、合理设置map和reduce个数:map和reduce的个数不能设置的太多也不能太少,太少会导致task等待,从任务执行时间延长。设置的太多会导致map和reduce任务之间竞争资源,从而导致一些任务超时等问题。

b、设置map和reduce共存:通过设置slowstart.completedmaps 参数,当map任务执行到一定程度的时候,同时开启reduce任务,从而减少reduce等待时间。

c、尽量避免使用reduce:因为当reduce连接数据集的时候会产生大量的网络消耗。

d、合理设置reduce段的buffer:默认情况下buffer有一个阀值,当数据量达到这个阀值的时候,buffer中的数据就会写到磁盘中,然后reduce再从磁盘中获取所有的数据,也就是说reduce和buffer没有直接关联,中间多了一个数据的写入磁盘---》磁盘中数据读取的过程,这个弊端可以通过配置进行解决:mapred.job.reduce.input.buffer.percent的默认值为0.0,当这个值大于0的时候,保留一定比例的内存来读取buffer中数据直接提供给reduce。这样设置buffer需要内存,读取数据也需要内存,而reduce运行也需要内存,所以运行任务时应该合理分配。

4、I/O传输

a、采用SequnceFileInputFormat二进制文件

b、采用压缩的机制,安装LZO和Snappy编码器

5、数据倾斜

1、数据倾斜的现象

a、在某些区域的数据远大于其他区域------数据频率倾斜

b、部分数据的记录远远大于平均值---------数据大小倾斜

2、如何收集数据倾斜的数据

在reduce方法中设置一个最大值 ,在log中打印,具体方法如下:

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、数据倾斜的解决办法

a、 抽样确定分区的界值

在原始数据中抽样得到的结果集来预设分区的边界值。

b、自定义分区

基于输出的键的背景知识来自定义分区。比如map输出的键是一本书的单词,这些单词中有一些专业的词出现比较多,那么就可以将这些词分给专门的reduce去处理,剩下其他的词交给其他的reduce。

c、combine机制

combine机制是map阶段提前进行计算,这样大大减小了I/O网络传输。使用combine可以减小数据倾斜,在可能的情况下,combine的目的是进行聚合和精简数据的。

d、使用map join,避免使用reduce join

6、参数配置

1、资源方面的配置

a、以下参数是在用户自己的 mr 应用程序中配置就可以生效(mapred-default.xml)

b、以下要在yarn启动之前配置才能生效:

c、shuffle阶段性能优化的相关参数配置,要在yarn启动之前配置才能生效

2、容错方面配置

三、HDFS小文件的优化方法

HDFS中大量小文件的弊端:

在HDFS中存储文件,都会产生一个对应的索引,一个索引所占大小大概在150byte左右,如果产生大量的小文件一方面会占用namenode的内存,另一方面大量的索引文件也会导致索引速度变慢。

解决大量小文件的办法:

1、hadoop Archive:

是一种将HDFS中的文件进行归档的工具,可以将大量小文件归档打包,最终生成一个HAR文件包。这样就减小了namenode内存使用。

2、采用CombineTextInputFormat的数据输入形式

CombineTextInputFormat是一种新的InputFormat,可以将大量小文件合并到一个独立的split(分片),同时也会考虑数据的存储位置。

3、使用SequnceFileInputFormat二进制文件

SequnceFile是一种由key/value的二进制文件,一般key为文件的路径和文件名,value为文件内容,则可以将大量小文件合并为一个大文件。

4、开启jvm重用

默认情况一个map执行会启动一个jvm,启动jvm重启机制后,当一个map执行完之后jvm不关闭继续执行下一个jvm。当执行大量小文件的job时,开启jvm重用可以提高45%以上的效率。

具体方式:mapreduce.job.jvm.numtasks的值在10-20之间。

猜你喜欢

转载自blog.csdn.net/hfweather/article/details/82595395