MapReduce的性能调优

MR调优主要分为3步骤:

  1. 在代码书写时优化,如尽量避免在map端创建变量等,因为map端是循环调用的,创建变量会增加内存的消耗,尽量将创建变量放到setup方法中;

  2. 配置调优,可以在集群配置和任务运行时进行调优,具体如下:

    1)调优总的原则给shuffle过程尽量多提供内存空间,在map端,可以通过避免多次溢出写磁盘来获得 佳性能(相关配置io.sort.*,io.sort.mb);在reduce端,中间数据全部驻留在内存时,就能获得最佳性能,但是默认情况下,这是不可能发生的,因为一般情况所有内存都预留给reduce含函数(如需修改 需要配置mapred.inmem.merge.threshold,mapred.job.reduce.input.buffer.percent)。如果能够根据情况对shuffle过程进行调优,对于提供MapReduce性能很有帮助。
     (2)一个通用的原则是给 shuffle过程分配尽可能大的内存,当然你需要确保map和reduce有足够的内存来运行业务逻辑。因此在实现Mapper和Reducer时,应该尽量减少内存的使用,例如避免在Map中不断地叠加。 运行map和 reduce任务的JVM,内存通过mapred.child.java.opts属性来设置,尽可能设大内存。容器的内存大小通过mapreduce.map.memory.mb和mapreduce.reduce.memory.mb来设置,默认都是1024M。
     (3)通过以下方法提高排序和缓存写入磁盘的效率:
          A)调整mapreduce.task.io.sort.mb大小,从而避免或减少缓存溢出的数量。当调整这个参数时, 好同时检测Map任务的JVM的堆大小,并必要的时候增加堆空间。 
          B)mapreduce.task.io.sort.factor属性的值提高100倍左右,这可以使合并处理更快,并减少磁盘的访问。 
          C)为K-V提供一个更高效的自定义序列化工具,序列化后的数据占用空间越少,缓存使用率就越高。
          D)提供更高效的Combiner(合并器),使Map任务的输出结果聚合效率更高。 
          E)提供更高效的键比较器和值的分组比较器。
     (4)输出依赖于作业中Reduce任务的数量,下面是一些优化建议:
          A)压缩输出,以节省存储空间,同时也提升HDFS写入吞吐量
          B)避免写入带外端文件(out-ofband side file)作为Reduce任务的输出
          C)根据作业输出文件的消费者的需求,可以分割的压缩技术或许适合
          D)以较大块容量设置,写入较大的HDFS文件,有助于减少Map任务数
     (5)Map/Reduce端调优
          通用优化 Hadoop默认使用4KB作为缓冲,这个算是很小的,可以通过io.file.buffer.size来调高缓冲池大小。
          map端优化,即避免写入多个spill文件可能达到最好的性能,一个spill文件是 好的。通过估计map端的输出大小,设置合理的mapreduce.task.io.sort.*属性,使得spill文件数量 小。例如尽可能调大mapreduce.task.io.sort.mb。
          reduce端优化,如果能够让所有数据都保存在内存中,可以达到 佳的性能。通常情况下,内存都保留给reduce 函数,但是如果reduce函数对内存需求不是很高,将mapreduce.reduce.merge.inmem.threshold(触发合并的map输出文件数)设为0,mapreduce.reduce.input.buffer.percent(用于保存map输出文件的堆内存比例)设为1.0,可以达到很好的性能提升。在TB级别数据排序性能测试中,Hadoop就是通过将reduce的中间数据都保存在内存中胜利的。
  3. 修改源代码
    如果上述两种调优已经无法满足整个集群的要求,那么就需要修改框架的源代码,重新编译,已达到特定的优化需求

点击此处
隐藏目录