系统调整
1. io.file.buffer.size
用来设置缓存的大小。不论是对硬盘或者是网络操作来讲,较大的缓存都可以提供更高的数据传输,但这也就意味着更大的内存消耗和延迟。这个参数要设置为系统页面大小的倍数,以byte为单位,默认值是4KB,一般情况下,可以设置为64KB(65536byte)
2. df.block.size
对于一个Mapreduce作业(尤其是用子类FileInputFormat定义输入格式的作业),对文件的每个数据块会启用一个map任务来处理。这就意味这数据块的大小显著地影响Mapreduce作业的效率。
3. dfs.namenode.handler.count
NameNode有一个工作线程池用来处理客户端的远程过程调用及集群守护进程的调用。处理程序数量越多意味着要更大的池来处理来自不同DataNode的并发心跳以及客户端并发的元数据操作。对于大集群或者有大量客户端的集群来说,通常需要增大参数dfs.namenode.handler.count的默认值10。设置该值的一般原则是将其设置为集群大小的自然对数乘以20,即20logN,N为集群大小。
如果该值设的太小,明显的状况就是DataNode在连接NameNode的时候总是超时或者连接被拒绝,但NameNode的远程过程调用队列很大时,远程过程调用延时就会加大。症状之间是相互影响的,很难说修改dfs.namenode.handler.count就能解决问题,但是在查找故障时,检查一下该值的设置是必要的。
python -c 'import math ; print int(math.log(6) * 20)'
4. io.sort.mb
MapTask运算产生中间数据并非直接就简单的写入磁盘,会利用到内存buffer进行缓存,并在内存buffer中进行一些预排序来优化整个map的性能,每一个map都会对应存在一个内存buffer,这个buffer默认是100MB大小,但是这个大小是可以根据job提交时的参数设定来调整的。
当Map产生数据非常大时,把io.sort.mb调大则map在整个计算过程中spill的次数就势必会降低,map task对磁盘的操作就会变少,如果map tasks的瓶颈在磁盘上,这样调整就会大大提高map的计算性能。
5. io.sort.spill.percent
上述buffer并不一定能将全部的map输出缓存下来,当map输出超出一定阈值(比如100M),那么map就必须将该buffer中的数据写入到磁盘中去。当buffer被写满到一定程度(比如80%)时,就开始进行spill,即写入磁盘。
此参数影响spill频繁程度,进而影响MapTask运行周期对磁盘的读写频率。通常不需要人为的调整,调整io.sort.mb对用户来说更加方便。
6. io.sort.factor
Map输出会生成一个或者多个spill文件,在正常退出之前,需要将这些spill合并(merge)成一个,所以map在结束之前还有一个merge的过程。此参数表示最多能有多少并行的stream向merge文件中写入。当map中间结果非常大时,调大io.sort.factor,有利于减少merge次数,进而减少map对磁盘的读写频率,有可能达到优化作业的目的。
7. mapred.compress.map.output
通过压缩减少写入读出磁盘的数据量。
配套参数:mapred.map.output.compression.codec (org.apache.hadoop.io.compress.SnappyCodec)
选项 | 类型 | 默认值 | 描述 |
io.sort.mb | int | 100 | 缓存map中间结果的buffer大小(in MB) |
io.sort.record.percent | float | 0.05 | io.sort.mb中用来保存map output记录边界的百分比,其他缓存用来保存数据 |
io.sort.spill.percent | float | 0.8 | map开始做spill操作的阈值 |
io.sort.factor | int | 10 | 做merge操作时同时操作的stream数上限。 |
min.num.spill.for.combine | int | 3 | combiner函数运行的最小spill数 |
mapred.compress.map.output | boolean | FALSE | map中间结果是否采用压缩 |
mapred.map.output.compression.codec | class name | org.apache.hadoop.io.compress.DefaultCodec |
Reduce端调整,
8. mapred.reduce.parallel.copies
shuffle实际上就是从不同的已经完成的map上copy属于自己这个reduce的部分数据,由于map通常有许多个,所以对一个reduce来说,下载也可以是并行的从多个map下载,这个并行度是可以调整的。
调大此参数,对map很多的job的情况则有利于reduce更快的获取属于自己部分的数据。
9. io.sort.factor
此参数配置同样会影响reduce进行merge时的行为,当发现reduce在shuffle阶段iowait非常的高的时候,就有可能通过调大这个参数来加大一次merge时的并发吞吐,优化reduce效率。
选项 | 类型 | 默认值 | 描述 |
mapred.reduce.parallel.copies | int | 5 | 每个reduce并行下载map结果的最大线程数 |
mapred.reduce.copy.backoff | int | 300 | reduce下载线程最大等待时间(in sec) |
io.sort.factor | int | 10 | 同上 |
mapred.job.shuffle.input.buffer.percent | float | 0.7 | 用来缓存shuffle数据的reduce task heap百分比 |
mapred.job.shuffle.merge.percent | float | 0.66 | 缓存的内存中多少百分比后开始做merge操作 |
mapred.job.reduce.input.buffer.percent | float | 0 | sort完成后reduce计算阶段用来缓存数据的百分比 |
yarn.scheduler.maximum-allocation-mb : 一次申请分配内存资源的最大数量
yarn.nodemanager.vmem-pmem-ratio : 使用1M物理内存,最多可以使用的虚拟内存数量
这个比率的控制影响着虚拟内存的使用,当yarn计算出来的虚拟内存,比在mapred-site.xml里的mapreduce.map.memory.mb或mapreduce.reduce.memory.mb(均默认为1024M)的2.1倍还要多时,就会由NodeManage守护进程kill掉AM容器,从而导致整个MR作业运行失败,我们只需要调大这个比率即可,避免发生这种异常。具体调大多小,可根据具体情况来设置。
yarn.nodemanager.resource.memory.mb : 默认值为8192M,节点所在物理主机的可用物理内存总量。13. 基于yarn的公平调度器配置