抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

码猿不正经

1.MapReduce跑得慢的原因

Mapreduce程序效率的瓶颈在于两点:

  1. 计算机性能:CPU、内存、磁盘健康状况以及网络速度都可能影响MapReduce任务的执行效率。
  2. I/O 操作优化:
    • 数据倾斜:某些任务由于数据分布不均匀,导致部分任务处理数据量远大于其他任务。
    • map和reduce数设置不合理:太多或太少的任务可能导致资源竞争或等待时间延长。
    • reduce等待过久:Map任务完成后Reduce任务才开始执行,如果Map任务执行时间过长,将导致Reduce等待。
    • 小文件过多:HDFS上的小文件过多会增加NameNode的内存负担,并可能导致大量的Map任务。
    • 大量的不可分块的超大文件:大文件如果不可分块,将不能有效利用集群的并行处理能力。
    • spill次数过多:Map阶段数据处理时,内存缓冲区溢出到磁盘的次数过多,增加了I/O操作。
    • merge次数过多:Map任务结束前,需要将溢写到磁盘的多个文件合并,如果合并次数过多,也会增加处理时间。

2.MapReduce优化方法

  1. 数据输入优化:

    • 合并小文件:在执行mr任务前将小文件进行合并,大量的小文件会产生大量的map任务,增大map任务装载次数,而任务的装载比较耗时,从而导致mr运行较慢。
    • 采用ConbinFilelnputFormat来作为输入,它可以将多个文件合并成一个单独的 split,解决输入端大量小文件场景。
  2. Map阶段优化:

    • 减少spill次数:通过调整io.sort.mb及sort.spill.percent参数值,增大触发spil的内存上限,减少spill次数,从而减少磁盘 I/O。
    • 减少merge次数:通过调整io.sort.factor参数,增大merge的文件数目,减少merge的次数,从而缩短mr处理时间。
    • 在map之后先进行combine处理,减少I/O。
  3. Reduce阶段优化:

    • 合理设置map和reduce数:两个都不能设置太少,也不能设置太多。太少,会导致task等待,延长处理时间;太多,会导致map、reduce任务间竞争资源,造成处理超时等错误。
    • 设置map、reduce共存:调整slowstart.completedmaps参数,使map运行到一定程度后,reduce也开始运行,减少reduce的等待时间。
    • 规避使用reduce以减少网络消耗,因为Reduce在用于连接数据集的时候将会产生大量的网络消耗。
    • 合理设置reduc端的buffer ,默认情况下 ,数据达到一个阈值的时候 ,buffer中的数据就会写入磁盘 ,然后reduce会从磁盘中获得所有的数据。也就是说 ,buffer和reduce是没有直接关联的 ,中间多个一个写磁盘->读磁盘的过程 ,既然有这个弊端 ,那么就可以通过参数来配置 ,使得buffer中的一部分数据可以直接输送到reduce ,从而减少IO开销mapred.job.reduce.input.buffer.percent ,默认为0.0。当值大于0的时候 ,会保留指定比例的内存读buffer中的数据直接拿给reduce使用。这样一来 ,设置buffer需要内存 ,读取数据需要内存 ,reduce计算也要内存 ,所以要根据作业的运行情况进行调整。
  4. IO传输优化:

    • 采用数据压缩的方式,减少网络IO的的时间。安装Snappy和LZOP压缩编码器。
    • 使用二进制文件格式如 SequenceFile 来提高 IO 效率。
  5. 数据倾斜问题:

    • 数据倾斜现象:

      • 数据频率倾斜——某一个区域的数据量要远远大于其他区域。
      • 数据大小倾斜——部分记录的大小远远大于平均值。
    • 如何收集倾斜数据:

      • 在reduce方法中加入记录map输出键的详细情况的功能:

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        public static final String MAX_VALUES = "skew.maxvalues";
        private int maxValueThreshold;
        @Override
        public void configure(JobConfjob) {
        maxValueThreshold =job.getInt(MAX_VALUES, 100);
        }
        @Override
        public void reduce(Text key, Iterator<Text> values,OutputCollector<Text, Text> output,Reporter reporter) throws IOException {
        inti = 0;
        while (values.hasNext()) {
        values.next();
        i++;
        }
        if (++i > maxValueThreshold){
        log.info("Received " + i + " values for key " + key);
        }
        }
    • 减少数据倾斜的方法:

      方法1:抽样和范围分区

      ​ 可以通过对原始数据进行抽样得到的结果集来预设分区边界值。

      方法2:自定义分区

      ​ 另一个抽样和范围分区的替代方案是基于输出键的背景知识进行自定义分区。例如,如果map输出键的单词来源于一本书。其中大部分必然是省略词(stopword)。那么就可以将自定义分区将这部分省略词发送给固定的-部分reduce实例。而将其他的都发送给剩余的reduce实例。

      方法3:Combine

      ​ 使用Combine可以大量地减小数据频率倾斜和数据大小倾斜。在可能的情况下,Combine的目的就是聚合并精简数据。

  6. 常用的调优参数:

    • 资源相关参数

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

        配置参数 参数说明
        mapreduce.map.memory.mb 一个Map Task可使用的资源上限(单位:MB),默认为1024。 如果Map Task实际使用的资源量超过该值 ,则会被强制杀死。
        mapreduce.reduce.memory.mb 一个Reduce Task可使用的资源上限(单位:MB),默认为1024。如果Reduce Task实际使用的资源量超过该值,则会被强制杀死。
        mapreduce.map.cpu.vcores 每个Map task可使用的最多cpu core数目 ,默认值: 1
        mapreduce.reduce.cpu.vcores 每个Reduce task可使用的最多cpu core数目 ,默认值: 1
        mapreduce.reduce.shuffle.parallelcopies 每个reduce去map中拿数据的并行数。默认值是5
        mapreduce.reduce.shuffle.merge.percent buffer中的数据达到多少比例开始写入磁盘。默认值0.66
        mapreduce.reduce.shuffle.input.buffer.percent buffer大小占reduce可用内存的比例。默认值0.7
        mapreduce.reduce.input.buffer.percent 指定多少比例的内存用来存放buffer中的数据,默认值是0.0
      2. 应该在yarn启动之前就配置在服务器的配置文件中才能生效(yarn-default.xml)

        配置参数 参数说明
        yarn.scheduler.minimum-allocation-mb 1024 给应用程序container分配的最小内存
        yarn.scheduler.maximum-allocation-mb 8192 给应用程序container分配的最大内存
        yarn.scheduler.minimum-allocation-vcores 1 每个container申请的最小CPU核数
        yarn.scheduler.maximum-allocation-vcores 32 每个container申请的最大CPU核数
        yarn.nodemanager.resource.memory-mb 8192 给containers分配的最大物理内存
      3. shuffle性能优化的关键参数 ,应在yarn启动之前就配置好(mapred-default.xml)

        配置参数 参数说明
        mapreduce.task.io.sort.mb 100 shuffle的环形缓冲区大小 ,默认100m
        mapreduce.map.sort.spill.percent 0.8 环形缓冲区溢出的阈值 ,默认80%
    • 容错相关参数(mapreduce性能优化)

      配置参数 参数说明
      mapreduce.map.maxattempts 每个Map Task最大重试次数,一旦重试参数超过该值,则认为Map Task运行失败 ,默认值:4。
      mapreduce.reduce.maxattempts 每个Reduce Task最大重试次数 ,一旦重试参数超过该值 ,则认为Map Task运行失败 ,默认值:4。
      mapreduce.task.timeout Task超时时间 ,经常需要设置的一个参数 ,该参数表达的意思为:如果一个task在一定时间内没有任何进入 ,即不会读取新的数据, 也没有输出数据,则认为该task处于block状态,可能是卡住了,也 许永远会卡主 ,为了防止因为用户程序永远block住不退出 ,则强 制设置了一个该超时时间(单位毫秒),默认是600000。如果你 的程序对每条输入数据的处理时间过长(比如会访问数据库,通过 网络拉取数据等),建议将该参数调大,该参数过小常出现的错误提示是“AttemptID:attempt_14267829456721_123456_m_000224_0 Timed out after 300 secsContainer killed by the ApplicationMaster.”。

3.HDFS小文件弊端及优化方法

  1. HDFS小文件弊端:

    ​ HDFS上每个文件都要在namenode上建立一个索引l,这个索引l的大小约为150byte,这样当小文件比较多的时候,就会产生很多的索引文件,一方面会大量占用namenode的内存空间,另一方面就是索引文件过大时的索引速度变慢。

  2. 解决方案:

    • Hadoop Archive

      ​ 一个高效地将小文件放入HDFS块中的文件存档工具。使用 hadoop archive 命令将多个小文件打包成一个 HAR 文件减少 NameNode 的内存使用允许对文件进行透明访问提高访问效率

    • Sequence file

      ​ sequence file由一系列的二进制key/value组成,如果key为文件名,value为文件内容,则可以将**大批小文件合并成一个大文件(SequenceFile)**。

    • CombineFilelnput Format

      ​ CombineFilelnputFormat是一种新的inputformat,使用它将多个文件合并成一个单独的split,同时它会考虑数据的存储位置,提高数据处理效率

    • 开启JVM重用

      ​ 对于大量小文件Job,可以开启JVM重用,会减少45%运行时间

      ​ JVM重用理解:一个map运行一个jvm,重用的话,在一个map在jvm上运行完毕后,jvm继续运行其他jvm。

      ​ 具体设置:mapreduce.job.jvm.numtasks值在10-20之间。

4.MapReduce怎么解决数据均衡问题,如何确定分区号?

​ 数据均衡问题指的就是某个节点或者某几个节点的任务运行的比较慢,拖慢了整个Job的进度。实际上数据均衡问题就是数据倾斜问题 ,解决方案同解决数据倾斜的方案。(见上一题)

​ MapReduce中分区默认是按hashcode来分的 ,即根据keyhashCodeReduce Tasks个数取模得到。

​ 用户可以自定义分区类 ,需要继承系统的Partitioner类 ,重写getPartition()方法即可。

5. Hadoop中job和Tasks之间的区别是什么

​ 编写好的一个程序 ,我们称为Mapreduce程序 ,一个Mapreduce程序就是一个Job ,而一个Job里面可以有一个或多个Task ,Task又可以区分为Map Task和Reduce Task.

评论