如果存在大量小文件,默认每个小文件会构建一个分片,比较浪费资源,可以使用 CombineTextInputFormat 代替TextInputFormat,将多个小文件合并为一个分片:
job.setInputFormatClass(CombineTextInputFormat.class);
//最大分片 128M
CombineTextInputFormat.setMaxInputSplitSize(job, 134217728);
//最小分片 100M
CombineTextInputFormat.setMinInputSplitSize(job, 104857600);
Mapper 阶段生成的数据会首先写到缓冲区(默认大小为100M),如果占用达到 80%开始spill 如果内存允许的情况下可以增大缓冲区的大小以减少 spill 的次数,从而减少磁盘IO。
修改 mapred-site.xml 文件:
<property>
<name>mapreduce.task.io.sort.mbname>
<value>200value>
property>
<property>
<name>mapreduce.map.sort.spill.percentname>
<value>0.9value>
property>
Mapper 阶段生成的数据,默认每次生成10个小文件开始进行合并,如果磁盘空间允许,可以增大个数减少merge的次数,从而减少磁盘IO。
修改 mapred-site.xml 文件
<property>
<name>mapreduce.task.io.sort.factorname>
<value>15value>
property>
默认情况下 Reduce 会主动去拿 Mapper 阶段的结果,并写入缓冲区然后持久化到硬盘,处理时再从硬盘中取出,如果内存允许的情况下,可以将 Mapper 阶段的结果放在内存中,读取时直接从内存中获取数据,从而提高效率。
修改mapred-site.xml 文件:
<property>
<name>mapreduce.reduce.input.buffer.percentname>
<value>0.4value>
property>
MapReduce运行过程中,如果出现MapTask或者ReduceTask由于网络、资源等外部因素导致失败,AppMaster会检测到Task的任务失败,立即重新分配资源,重新运行该失败的Task,默认情况下会重试4次,如果重试4次以后依旧没有运行成功,那么整个Job会终止,程序运行失败。可以根据实际情况修改重试次数。
修改 mapred-site.xml 文件:
<property>
<name>mapreduce.map.maxattemptsname>
<value>8value>
property>
<property>
<name>mapreduce.reduce.maxattemptsname>
<value>8value>
property>
MapReduce模型将Job作业分解成Task任务,然后并行的运行Task任务,当一个Job有成百上千个Task时,可能某个 Task 任务运行缓慢,导致整体 Job 缓慢。有可能是硬件老化或软件配置错误,但检测问题具体原因很难,因为任务总能成功执行完,尽管比预计时间长。这种情况下Hadoop不会尝试诊断或修复执行慢的任务。
而推测执行是指在一个Task任务运行比预期慢时,程序会尽量检测并启动另一个相同的任务作为备份,但是如果同时启动两个相同的任务他们会相互竞争,导致推测执行无法正常工作,这对集群资源也是一种浪费。
只有在一个Job作业的所有Task任务都启动之后才会启动推测任务,并只针对已经运行一段时间(至少一分钟)且比作业中其他任务平均进度慢的任务。一个任务成功完成后任何正在运行的重复任务都将中止。如果原任务在推测任务之前完成则推测任务就会被中止,同样,如果推测任务先完成则原任务就会被中止。
推测任务只是一种优化措施,它并不能使Job作业运行的更加可靠。如果有一些软件缺陷造成的任务挂起或运行速度慢,依靠推测执行是不能成功解决的。默认情况下推测执行是启用的,可根据集群或每个作业,单独为map任务或reduce任务启用或禁用该功能。
修改 mapred-site.xml 文件:
<property>
<name>mapreduce.map.speculativename>
<value>falsevalue>
property>
<property>
<name>mapreduce.reduce.speculativename>
<value>falsevalue>
property>