本文为《hadoop技术内幕:深入解析MapReduce架构设计与实现原理》一书第9章《Hadoop性能调优》的总结。

MapReduce调优总结与拓展-LMLPHP

图1 Hadoop层次结构图

从管理员角度进行调优

1.硬件选择

master配置(可靠性,内存,CPU主频等)优于slave。

2.操作系统参数调优

  1)增大同时打开的文件描述符和网络连接上限

    ulimit 将允许同时打开的文件描述符数增大到一个合适的值。

    net.core.somaxconn

    定义了系统中每一个端口最大的监听队列的长度,这是个全局的参数,默认值为128(通常要增加大1024或更多)。

    关于这个参数,见这篇博文:http://blog.csdn.net/taolinke/article/details/6800979

  2)关闭swap分区

    避免使用swap分区。设置vm.swappiness

  3)设置合理的预读取缓冲大小

    blockdev命令

  4)文件系统选择与配置

  不同的文件系统会有一定的差别。

  在Linux文件系统中,启动noatime属性。具体操作见这篇文章:http://www.cnblogs.com/allegro/archive/2011/04/18/2019466.html

  5)I/O调度器选择

  详情可参见AMD的白皮书《Hadoop performance tuning guide》

  

3.JVM参数调优

  关键词:JVM FLAGS、垃圾回收机制。参见《Hadoop performance tuning guide》

4.Hadoop参数调优

  1)合理规划资源

    a设置合理的槽位数目

    b编写健康监测脚本

  2)调整心跳配置

    a调整心跳间隔

    b启用带外心跳

    

  3)磁盘块配置

    

  4)设置合理的RPCHandler和HTTP线程数目

    a配置RPC Handler数目

    b配置HTTP线程数目

  5)慎用黑名单机制

    黑名单节点数目越多,系统吞吐率和计算能力越低。

  6)启用批量任务调度

  7)选择合适的压缩算法

    mapred.compress.map.output 设为true

    设置mapred.map.output.compression.codec的值为合适的值。

  8)启用预读取机制

从用户角度进行调优

1.应用程序编写规范

  1)设置combiner,作用是减少map端的中间输出。

  2)选择合适的Writable类型,Map Task和Reduce Task的输入输出都是Writable类型。

2.作业级别参数调优

  1)规划合理的任务数目

  2)增加输入文件副本数目

    输入文件副本少,一个可能的后果是当多个任务并行读取一个副本时,会出现读取瓶颈。

    在hdfs-site.xml中修改dfs.replication的值。

  3)启动推测执行机制

    将运行较慢的任务在另一个节点上启动,2个任务同时运行。其中1个提前完成后会将另一个杀死。

    属性:mapred.map.tasks.speculative.execution 默认true

  4)设置容忍度

    分为作业级别和任务级别的失败容忍。

    属性:mapred.max.map.failures.percent 默认0,如果是5表示5%

         mapred.map.max.attempts 默认为4

    

  5)适当打开JVM重用功能

    当任务较小时,避免JVM重复启动占用很多时间。mapred.job.reuse.jvm.num.tasks 默认为1

  6)设置任务超时时间

    超时之后,TaskTracker将任务杀死,然后在另一个节点重新启动一个。

    属性设置:

    mapred.task.timeout 默认60 000(单位毫秒,也就是10分钟)

  7)合理使用DistributedCache

    了解下DistributedCache就知道该怎么用这个了。具体细节是:在调用任务前将文件上传到HDFS可以在作业运行期间将DistributedCache内的这些文件下载到public目录下,好处是:public目录下的文件是共享的,后续任务不必重新下载。

  8)合理控制Reduce Task的启动时机

    注意:启动过早会占用slot资源,造成slot Hoarding现象;启动过晚会造成资源获取较晚从而延长作业运行时间。

    旧版  mapred.reduce.slowstart.completed.maps  默认值0.05

    新版  mapreduce.job.reduce.slowstart.completed.maps  默认0.05

  9)跳过坏记录

    mapred.skip.attempts.to.start.skipping 当任务失败次数达到此值时,才会进入skip mode,即启用跳过坏记录功能。

    mapred.skip.map.skip.records  最多允许跳过的坏记录的个数

    mapred.skip.reduce.max.skip.groups  

    mapred.skip.out.dir    顾名思义

  10)提高作业优先级

   解释一下怎么设置作业的优先级:设置mapred.job.priority(默认NORMAL)或者mapreduce.job.priority(NORMAL)。总共有5个优先级可选:VERY_HIGH,HIGH,NORMAL,LOW,VERY_LOW。

   优先级主要作用在于作业调度器会根据优先级分配资源(slot数目或者在YARN中更加灵活的内存容量)。

   

3.任务级别参数调优

  1)Map Task调优

    高效利用环形缓冲区。具体方法是设置合适的io.sort.record.percent,这个属性的含义是索引占buffer的比例。索引或者数据达到了缓冲区的io.sort.spill.percent时,就会触发flush,将数据读入磁盘。根据索引大小(一般为16B)和key/value大小,设置合适的io.sort.record.percent值=16/(16+R)(R为key/value大小),这样就可以最大限度利用圆形缓冲区了。    

  2)Reduce Task调优

    主要目的是减少磁盘的写入。

    写入磁盘的条件为:

    a内存使用率超过heapsize*(mapred.job.shuffle.input.buffer.percent)达到mapred.job.shuffle.merge.percent(默认为0.66);

    b内存中文件数目超过mapred.inmem.merge.percent.threshold(默认是1000);

    c文件大小超过阈值heapsize*(mapred.job.shuffle.input.buffer.percent)*0.25。

    通过调整这些属性值,可以控制磁盘的写入。

05-11 22:04