• mapreduce的调度算法和job调优


    调度算法: mapreduce当有很多的作业在执行的时候,是按照什么顺序去执行的?

      调度算法顺序需要关注:
        1.提高作业的吞吐量.
        2.要考虑优先级.
      三种调度器:如果作业跑不完,并且机器资源利用率比较低,这时候就可以考虑这些东西
        1.FifoScheduler,默认的调度算法,先进先出的方式处理应用,只有一个队列可提交应用,没有应用优先级可以配置.
        2.CapacityScheduler,容量调度器.多队列的,依靠作业,如果需求资源少了,优先级就会高一些,需求资源多了,优先级就会低一些.
        3.FairScheduler:公平调度器,多队列的,多用户共享资源.程序在运行的时候可以在客户端设置优先级,也可以设置抢占.
      最简单的使用方法:
        1.配置FairScheduler:
          修改配置文件mapred-site.xml,然后重启集群即可
          更多配置在:conf/fair-scheduler.xml
          <property>
            <name>mapred.jobtracker.tasktracker</name>
              <!-- <value>org.apache.hadoop.mapred.JobQueueTaskScheduler</value> -->
            <value>org.apache.hadoop.mapred.FairSchedler</value>
          </property>
        2.配置CapacityScheduler:
          修改配置文件mapred-site.xml,容量调度器是多队列的,需要指定的,有一个默认的,default
          更多配置在:conf/capacity-scheduler.xml
          <property>
            <name>mapred.jobtracker.tasktracker</name>
            <value>org.apache.hadoop.mapred.CapacityTaskScheduler</value>
          </property>
          <property>
            <name>mapred.queue.names</name>
            <value>default</value>
          </property>

    mapredece的job进行调优: 关注配置文件mapred-default.xml,作业的调优跟具体的环境有关

      从两个方面考虑,一个是map阶段,一个是reduce阶段
      一个文件起一个map任务,如果存在大量的小数据,会有大量的任务运行,会造成资源的浪费,可以使用SequenceFile.我们的map任务和reduce任务本身都是java进程,我们在启动map任务和reduce任务的话,实际是在启用java进程,就会耗费大量的资源.将大量的小文件交给一个map来处理,可以自定义CombineFileInputFormat.
      小文本合成一个大文件来运行效率其实是不相当的,五个不同机器上的小文件用一个map来处理,势必产生网络的传输.这时候也会占用很多的时间,但是这个相比每一个文件占用一个map来说处理时间要少一些.最好的办法就是不要在hdfs中放大量的小文件.
      推测执行:作业的运行的时候,如果有的比较慢,程序就会担心那个任务是不是比较慢,会影响整个作业的运行呀,那么再起一个相同任务去运行.也就是说对于同一份数据源有两个任务同时在运行,谁先结束就使用谁的,谁先结束就是用谁的,没有结束的杀死.
      推测执行在整个集群上应该要关闭,特定需要的作业单独开启,一般可以省下5%-10%的集群资源.
        mapred.map.task.speculative.execution=true;
        mapred.reduce.task.speculative.execution=false ;
        资源不紧张的时候可以开启.
      开启JVM重用:
        开启进程就等于新开一个jvm,为了节省资源,开启虚拟机的重用,可以不用关闭虚拟机,在这里边再起map,再起reduce就可以了,这叫开启jvm的重用.
        mapred.job.resue.jvm.tasks=-1;
      增加InputSplit的大小:
        mapred.min.split.size=268435456
        因为一个InputSplit代表一个map任务,InputSplit的数量少了,那么map任务就少了,执行占用的资源就少了,如果把InputSplit增大之后,一个map处理的资源也会多.InputSplit数量少了,但是map执行的数据多了.我们的map任务执行的InputSplit的话,意味着我们的map的任务已经开启了进程,初始化已经完成了,省下的就是重用这个进程,增大InputSplit之后,数据量就会加大,那么这个时候,一个map可以处理更多的数据,吞吐量就上来了.
      增大map输出的缓存.
        io.sort.mb=300
        map会产生输出,输出会送给reduce,reduce再把map任务的输出拿走之前,map要在内存中存放,当我们的map在内存中装不下的话,就会放到磁盘,100兆就会装不小.map往磁盘的每一次写都是一次IO的操作.资源的IO也是一个重量级的操作,所以就建议一次多写点东西,map的输出
      增加合并spill文件的数量:
        spill来自于:map任务的输出会先放到内存中,内存中装不小会先往磁盘上写,内存中装不下往磁盘上写的过程叫做spill,数据量如果很大的话,是需要spill很多次的,在磁盘就会产生这种 很多的小文件,这种很多的小文件,让reduce往这取可不行,那么map端就会把磁盘上的这种小文件合并到一起,合成一个文件.合成的过程就是合并,磁盘的这个操作和往写磁盘是一个道理,这如果说一次合并的多的话,合并的次数就会少,磁盘合并会耗费内存,也是会耗费cpu的,所以前边有map端操作,这还有spill操作,还有合并操作,那么应该把更多资源留给map,而不是留给后边的spill,这些过程又是不可少的,所以就只能使这样的过程占用的资源尽量少,也就是说运行的时间尽量短.一次性输出到磁盘多一些,合并的时候,一次合并多一些.
      map端输出压缩,推荐LZO压缩算法:
        mapred.compress.,ap.output=true ;
        mapred.map.output.compression.codec=com.hadoop.compression.lzo.LzoCodec;
      增大shuffle复制线程数:
        mapred.reduce.parallel=15;
        map端输出送到reduce端的这个过程叫做shuffle,shuffle的时候是reduce端发起请求,map端通过http复制过去,在复制的时候并发的线程数多了,意味着同时拷贝多份,换句话说就是吞吐量上去了.增加shuffle执行速度,减小shuffle运行的时间.并发量上去了,意味着网络占用磁盘带宽就高了,这种情况下,网络一般是没问题的,因为在内网并发线程数上去了,影响不是太大,所以这个东西是需要提高的.
      设置单个节点map,reduce执行数量,默认值是2
        把任务是改多了,意味着可以单机并行执行多个任务.会对内存占用增加.
        mapred.tasktracker.map.tasks.maxnum=2;
        mapred.tasktracker.reduce.tasks.maxnum=2;

  • 相关阅读:
    Offer快到碗里来,囊中之物-CAS
    SQL 两表一对多关联,主表某字段保存所有关联的id
    No Feign Client for loadBalancing defined
    Clean Code读书笔记 3--类
    Clean Code读书笔记(2)---函数
    Clean Code读书笔记(1)---有意义的命名
    [CF1354D] Multiset
    [CF1365E] Maximum Subsequence Value
    [CF1358D] The Best Vacation
    [CF463C] Gargari and Bishops
  • 原文地址:https://www.cnblogs.com/xiaolong1032/p/4590301.html
Copyright © 2020-2023  润新知