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;

posted @ 2015-06-20 10:36  小丁子  阅读(1294)  评论(0编辑  收藏  举报