hadoop为用户作业提供了多种可配置的参数,以允许用户根据作业特点调整这些值
使作业运行效率达到最优。
程序编写规范
(1)设置Combiner
如果是一大批MR程序,如果可以设置一个Combiner,Combiner可减少Map Task中间输出结果,从而减少各个Reduce Task的远程拷贝数据
量,最终表现为Map Task和Reduce Task执行时间缩短。
(2)选择合理的Writable类型
在MR模型中,Map Task和Reduce Task的输入和输出数据类型均为Writable。
为应用程序处理的数据类型选择合适的Writable类型可大大提升性能。比如处理整型数据时,直接采用IntWritable比先
以Text类型读入再转换成整型要高效。吐过如果输出的整型大部分可用一个或者两个字节保存,那么可直接采用VIntWritable或者
VLongWritable。它们采用了变长整型编码方式,可大大减少输出数据量。
作业级别参数调优
1.规划合理的任务数目
一个作业的任务数目对作业运行时间有重要的影响。如果一个作业的任务数目过多
(这意味着每个任务处理数据很少,执行时间很短),则任务启动时间所占比例将会大大增加;反之,如果一个
作业的任务数目过少(这意味着每个任务处理数据很多,执行时间很长),则可能会产生过多的溢写数据影响任务
执行性能,且任务失败后重新计算代价过大。
在hadoop中,每个Map Task处理一个Input Split。Input Split的划分方式
是由用户自定义的InputFormat决定的,默认情况下,由以下三个配置参数
决定:
mapred.min.split.size:Input Split的最小值(在mapred-site.xml中配置)
mapred.max.split.size:Input Split的最大值(在mapred-site.xml中配置)
dfs.block.size:HDFS中一个block大小(在hdfs-site.xml中配置)
每个作业的Reduce Task数目通常由用户决定。
用户可根据估算的Map Task输出数据量设置Reduce Task数目,以防止每个
Reduce Task处理的数据量过大造成大量写磁盘操作。
2.增加输入文件副本数
如果一个作业并行执行的任务数量非常多,
为防止多个任务并行读取一个文件内容造成瓶颈,用户可根据需要增加输入
文件的副本数目。用户可通过在客户端配置hdfs-site.xml中增加以下配置
选项修改文件副本数,比如将客户端上传的所有数据副本数设置为5:
<property>
<name>dfs.replication</name>
<value>5</value>
</property>
3.启用推测执行机制
当一个作业的某些任务运行速度明显慢于同作业的其他任务时,hadoop会在另一个节点上为“慢任务”启动一个备份任务,
这样,两个任务同时处理一份数据,而hadoop最终会将优先完成的那个任务的结果作为最终结果,并将另外一个任务kill掉。
启用推测执行机制
Hadoop版本号 配置参数 默认值
0.20.x,cdh 3 mapred.map.tasks.speculative.execution true
mapred.reduce.tasks.speculative.execution true
0.21.x,0.22.x mapreduce.map.speculative true
mapreduce.reduce.speculative true
4.设置失败容忍度
hadoop允许设置作业级别和任务级别的失败容忍度。
作业级别的容忍度是指Hadoop允许每个作业有一定比例的任务运行失败,
这部分任务对应的输入数据将被忽略(这些数据不会有产出);
任务级别的失败容忍是指Hadoop允许任务运行失败后再次在另外节点上尝试运行,如果一个任务经过若干次尝试运行后仍然运行失败,
那么Hadoop才会最终认为该任务运行失败。
5.适当打开JVM重用功能
方便任务的隔离,hadoop将每个任务放到一个单独的jvm中执行,
执行时间较短的任务,jvm启动和关闭将占用很大比例的时间,
为此,用户可启用jvm重用功能:
设置jvm重用
hadoop版本 配置参数 默认值
0.20.x,cdh3 mapred.job.reuse.jvm.num.tasks 1
0.21.x,0.22.x mapreduce.job.jvm.num.tasks 1
1表示每个jvm只能启动一个Task,若为-1则表示每个JVM可运行的Task数目不受限制。
6.设置任务超时时间
设置任务超时时间
hadoop版本号 配置参数默认值
0.20.x,CDH 3 mapred.task.timeout600 000(单位是毫秒,10分钟)
0.21.x,0.22.x mapreduce.task.timeout 600 000(单位是毫秒,10分钟)
7.合理使用DistributedCache
当用户的应用程序需要一个外部文件(比如字典、配置文件等)时,通常需要使用
DistributedCache将文件分发到各个节点上。
一般有两种方式得到外部文件:一种是外部文件与应用程序jar包一起放到客户端,
当提交作业时由客户端上传到hdfs的一个目录下,然后通过DistributedCache
分发到各个节点上;
第二种是事先将外部文件直接放到hdfs上。
第二种比第一种更高效。第二种方式不仅节省了客户端上传文件的时间,
还隐含着告诉DistributedCache:“请将文件下载到各节点的public级别
(而不是private级别)共享目录中”,这样,后续所有的作业科重用已经下载好的文件,
不必重复下载,即“一次下载,终生受益”。
8.合理控制Reduce Task的启动时机。。
从运算逻辑上讲,Reduce Task应晚于Map Task启动。在Hadoop中,合理
控制Reduce Task启动时机不仅可以加快作业运行速度,而且可提高系统资源利用率。
如果Reduce Task启动过早,则可能由于Reduce Task长时间占用Reduce slot资源造成
“slot Hoarding”现象,从而降低资源利用率;反之,如果Reduce Task启动
过晚,则会导致Reduce Task获取资源延迟,增加了作业在运行时间。
设置Reduce Task启动时机
hadoop版本号 配置参数 默认值
0.20.x,CDH 3 mapred.reduce.slowstart.completed.maps 0.05(Map Task完成数目达到5%时,开始启动Reduce Task)
0.21.x,0.22.x mapreduce.job.reduce.slowstart.completed.maps 同上
9.跳过坏记录
hadoop是用于处理海量数据的,对于大部分数据密集型应用而言,丢弃一条或者几条数据对最终结果的影响并不大,
正因为如此,hadoop为用户提供了跳过坏记录的功能。当一条或者几条数据记录导致任务运行失败时,
Hadoop可自动识别并跳过这些坏记录。。。。
10.提高作业优先级
一个作业的优先级越高,它能够获取的资源(指slot数目)也越多。
通常而言,在生产环境中,管理员已经按照作业重要程度对作业进行了分级,不同重要程度的作业
允许配置的优先级不同,用户不可以擅自调整。
设置作业优先级
Hadoop版本号 配置参数 默认值
0.20.x,CDH 3 mapred.job.priority NORMAL
0.21.x,0.22.x mapreduce.job.priority NORMAL
任务级别参数调优
1.MapTask调优
Map Task的输出结果被存放到一个环形缓冲区中,这个缓冲区的大小由参数“io.sort.mb”指定(默认100MB)。
该缓冲区主要由两部分组成:索引和实际数据。默认情况下,索引占整个buffer的比例为io.sort.record.percent(默认为
5%),剩下的空间全部存放数据,当且仅当满足一下任意一个条件时,才会触发一次flush,生成一个临时文件:
索引空间使用率达到比例为io.sort.spill.percent(默认是0.8,即80%)
数据空间使用率达到比例为io.sort.spill.percent(默认是0.8,即80%)
合理调整io.sort.record.percent值,可减少中间文件数目,提高任务执行效率。
例如:如果你的key/value非常小,则可以适当调大io.sort.record.percent值,以防止索引空间优先达到使用上限
触发flush。考虑到每条数据记录(一个key/value)需占用索引大小为16B,因此,建议io.sort.record.percent=16/(16+R)
其中R为平均每条记录的长度。
综上所述,用户可根据自己作业的特点对以下参数进行调优:
io.sort.mb
io.sort.record.percent
io.sort.spill.percent
2.ReduceTask调优
Reduce Task会启动多个拷贝线程从每个Map Task上读取相应的中间结果,
拷贝线程数由mapred.reduce.parallel.copies(默认为5)指定。对于每个待拷贝的文件,
如果文件大小小于一定阀值A,则将其放到内存中,否则以文件的形式存放到磁盘上。
如果内存中文件满足一定条件D,则会将这些数据写入磁盘,而当磁盘上文件数目达到io.sort.factor(默认是10)
时,进行一次合并。阀值A为:
heapsize*{mapred.job.shuffle.input.buffer.percent}*0.25
其中,heapsize是通过参数“mapred.child.java.opts”指定的,默认是200MB;
mapred.job.shuffle.input.buffer.percent默认大小为0.7。
条件D为以下两个条件中任意一个:
1.内存使用率(总的可用内存为heapsize*{mapred.job.shuffle.input.buffer.percent})
达到mapred.job.shuffle.merge.percent(默认是0.66)。
2.内存中文件数目超过mapred.inmem.merge.threshold(默认是1000)
综上所述,用户可根据自己作业的特点对以下参数调优:
1.mapred.reduce.parallel.copies
2.io.sort.factor
3.mapred.child.java.opts
4.mapred.job.shuffle.input.buffer.percent
5.mapred.inmem.merge.threshold
作者:u013361361 发表于2014-9-9 22:58:21
原文链接