原理图:

中间结果的排序与溢出(spill)流程图

map分析:

(1)、输入分片(input split):在进行mapreduce之前,mapreduce首先会对输入文件进行输入分片(input split)操作,每一个输入分片针对一个map任务,输入分片(input split)存储的并非数据本身,而是一个分片长度和一个记录数据的位置的数组,对于输入文件的分片大小,通常跟hdfs的块大小有关系,例如:hdfs的块大小为64MB,假如输入三个文件,1MB、98MB的文件,mapreduce就会对1MB的文件当作一个input split,对98MB的文件做两个input split(可以通过修改参数mapreduce.input.fileinputformat.split.minsize,使其大于块容量;由于CPU的约束,有时可以减少fileinputformat.split.minsize属性值,使它小于HDFS的块容量,从而提高资源的利用率。)。针对这三个分片操作,就有三个map任务要执行,但是这里每一个map任务执行的数据大小并不均匀,这里也是一个调优的重点。

(2)、map阶段就是通过程序员定义好的map函数输出键值<k1,v1>对了。每一个map task有一个环形内存缓冲区,用于存放map task的输出,也就是键值对<k2,v2>,已经被序列化,但没有排序。环形缓冲区默认大小100MB(mapreduce.task.io.sort.mb属性),一旦达到阀值0.8(mapreduce.map.sort.spill.percent属性),一个后台线程就把溢出(spill)内容写到Linux本地磁盘中的指定目录(mapreduce.cluster.local.dir)下的新建的一个溢出写文件,当超过阈值时,Map任务不会因为缓存溢出而被阻塞。但如果达到硬限制,Map任务会被阻塞,直到溢出行为结束。缓存的好处就是减少磁盘I/O的开销,提高合并和排序的速度。又因为默认的内存缓冲大小是100M(当然这个是可以配置的),所以在编写map函数的时候要尽量减少内存的使用,为shuffle过程预留更多的内存,因为该过程是最耗时的过程。

♥   线程会将记录基于键进行分区(通过 mapreduce.job.partitioner.class设置分区算法的类),在内存中将每个分区的记录按键排序(通过map.sort.class指定排序算法,默认快速排序org.apache.hadoop.util.QuickSort),然后写入一个文件。每次溢出,都有一个独立的文件存储。

♥   Map任务完成后,缓存溢出的各个文件会按键排序后合并到一个输出文件(通过mapreduce.cluster.local.dir指定输出目录,值为${hadoop.tmp.dir}/mapred/local)。合并文件的流的数量通过mapreduce.task.io.sort.factor指定,默认10,即同时打开10个文件执行合并。

说白点就是:在写磁盘前,要进行partition、sort和combine等操作。通过分区,将不同类型的数据分开处理,之后对不同分区的数据进行排序,如果有Combiner,还要对排序后的数据进行combine。等最后记录写完,将全部溢出文件合并为一个分区且排序的文件。(注意:在写磁盘的时候采用压缩的方式将map的输出结果进行压缩是一个减少网络开销很有效的方法!)

根据上面步骤,最好仅在Map任务结束的时候才能缓存写到磁盘中。

可以采用以下方法提高排序和缓存写入磁盘的效率:

  1. 调整mapreduce.task.io.sort.mb大小,从而避免或减少缓存溢出的数量。当调整这个参数时,最好同时检测Map任务的JVM的堆大小,并必要的时候增加堆空间。
  2. mapreduce.task.io.sort.factor属性的值提高100倍左右,这可以使合并处理更快,并减少磁盘的访问。
  3. 为K-V提供一个更高效的自定义序列化工具,序列化后的数据占用空间越少,缓存使用率就越高。
  4. 提供更高效的Combiner(合并器),使Map任务的输出结果聚合效率更高。
  5. 提供更高效的键比较器和值的分组比较器。

注:

如果指定了Combiner,可能在两个地方被调用。

  1. 当为作业设置Combiner类后,缓存溢出线程将缓存存放到磁盘时,就会调用;
  2. 缓存溢出的数量超过mapreduce.map.combine.minspills(默认3)时,在缓存溢出文件合并的时候会调用Combiner。

1、获取中间输出结果(Map侧)

Reducer需要通过网络获取Map任务的输出结果,然后才能执行Reduce任务,可以通过下述Map侧的优化来减轻网络负载:

  1. 通过压缩输出结果,mapreduce.map.output.compress设置为true(默认false),mapreduce.map.output.compress.codec指定压缩方式。
  2. Reduce任务是通过HTTP协议获取输出分片的,可以使用mapreduce.tasktracker.http.threads指定执行线程数(默认40)

reduce阶段:

Reduce任务是一个数据聚合的步骤。数量默认为1,而使用过多的Reduce任务则意味着复杂的shuffle,并使输出文件的数量激增。mapreduce.job.reduces属性设置reduce数量,也可以通过编程的方式,调用Job对象的setNumReduceTasks()方法来设置。一个节点Reduce任务数量上限由mapreduce.tasktracker.reduce.tasks.maximum设置(默认2)。

可以采用以下探试法来决定Reduce任务的合理数量:

# 每个reducer都可以在Map任务完成后立即执行
0.95 * (节点数量 * mapreduce.tasktracker.reduce.tasks.maximum)

另一个方法是

# 较快的节点在完成第一个Reduce任务后,马上执行第二个
1.75 * (节点数量 * mapreduce.tasktracker.reduce.tasks.maximum)

2. 获取中间输出结果(Reduce侧)

Reduce任务在结束时都会获取Map任务相应的分区数据,这个过程叫复制阶段(copy phase)。一个Reduce任务并行多少个Map任务是由mapreduce.reduce.shuffle.parallelcopies参数决定(默认5)。

由于网络问题,Reduce任务无法获取数据时,会以指数退让(exponential backoff)的方式重试,超时时间由mapreduce.reduce.shuffle.connect.timeout设置(默认180000,单位毫秒),超时之后,Reduce任务标记为失败状态。

3. 中间输出结果的合并与溢出

Reduce任务也需要对多个Map任务的输出结果进行合并,过程如上图,根据Map任务的输出数据的大小,可能将其复制到内存或磁盘。mapreduce.reduce.shuffle.input.buffer.percent属性配置了这个任务占用的缓存空间在堆栈空间中的占用比例(默认0.70)。

mapreduce.reduce.shuffle.merge.percent决定缓存溢出到磁盘的阈值(默认0.66),mapreduce.reduce.merge.inmem.threshold设置了Map任务在缓存溢出前能够保留在内存中的输出个数的阈值(默认1000),只要一个满足,输出数据都将会写到磁盘。

在收到Map任务输出数据后,Reduce任务进入合并(merge)或排序(sort)阶段。同时合并的文件流的数量由mapreduce.task.io.sort.factor属性决定(默认10)。

Map任务输出数据的所有压缩操作,在合并时都会在内存中进行解压缩操作。

借鉴:https://blog.csdn.net/u013980127/article/details/52807360

链接:https://blog.csdn.net/u012151684/article/details/72589302

Hadoop mapreduce过程分析的更多相关文章

  1. hadoop MapReduce Yarn运行机制

    原 Hadoop MapReduce 框架的问题 原hadoop的MapReduce框架图 从上图中可以清楚的看出原 MapReduce 程序的流程及设计思路: 首先用户程序 (JobClient) ...

  2. python - hadoop,mapreduce demo

    Hadoop,mapreduce 介绍 59888745@qq.com 大数据工程师是在Linux系统下搭建Hadoop生态系统(cloudera是最大的输出者类似于Linux的红帽), 把用户的交易 ...

  3. Hadoop MapReduce执行过程详解(带hadoop例子)

    https://my.oschina.net/itblog/blog/275294 摘要: 本文通过一个例子,详细介绍Hadoop 的 MapReduce过程. 分析MapReduce执行过程 Map ...

  4. Hadoop Mapreduce分区、分组、二次排序过程详解[转]

    原文地址:Hadoop Mapreduce分区.分组.二次排序过程详解[转]作者: 徐海蛟 教学用途 1.MapReduce中数据流动   (1)最简单的过程:  map - reduce   (2) ...

  5. Hadoop MapReduce编程 API入门系列之薪水统计(三十一)

    不多说,直接上代码. 代码 package zhouls.bigdata.myMapReduce.SalaryCount; import java.io.IOException; import jav ...

  6. Hadoop MapReduce编程 API入门系列之压缩和计数器(三十)

    不多说,直接上代码. Hadoop MapReduce编程 API入门系列之小文件合并(二十九) 生成的结果,作为输入源. 代码 package zhouls.bigdata.myMapReduce. ...

  7. Hadoop MapReduce例子-新版API多表连接Join之模仿订单配货

    文章为作者原创,未经许可,禁止转载.    -Sun Yat-sen University 冯兴伟 一.    项目简介: 电子商务的发展以及电商平台的多样化,类似于京东和天猫这种拥有过亿用户的在线购 ...

  8. Writing an Hadoop MapReduce Program in Python

    In this tutorial I will describe how to write a simpleMapReduce program for Hadoop in thePython prog ...

  9. Hadoop MapReduce编程学习

    一直在搞spark,也没时间弄hadoop,不过Hadoop基本的编程我觉得我还是要会吧,看到一篇不错的文章,不过应该应用于hadoop2.0以前,因为代码中有  conf.set("map ...

随机推荐

  1. POJ1222、POJ3279、POJ1753--Flip

    POJ1222-EXTENDED LIGHTS OUT POJ3279-Fliptile POJ1753-Flip Game 为什么将着三个题放一起讲呢?因为只要搞明白了其中一点,就可以一次3ac了- ...

  2. python小实例——tkinter实战(计算器)

    一.完美计算器实验一 import tkinter import math import tkinter.messagebox class calculator: #界面布局方法 def __init ...

  3. 第十七篇:WEB服务器之HTTP协议

    本篇主要为为了实现WEB服务器,其中包含了HTTP协议的理解,以及TCP的三次握手.四次挥手等方面相关知识,同时还包含了关于web浏览器与服务器之间的通信过程. 一.web浏览器 通常在我们上网时会在 ...

  4. c# 串行化事件

  5. 2.Git 结构

    1.Git 结构: 使用git add命令将写的代码暂存到暂存区:使用git commit命令将暂存区的代码提交到本地库: 2. Git 结构及其代码托管中心: workSpace:工作区(写代码). ...

  6. mybatis遍历map

    mytabis是可以遍历map的,试过很多其他的方法都不行,最终使用如下方法是可以的: 1.mapper.java如下(注意要加@Param注解,否则不行,我就在这里折腾了不少时间): int upd ...

  7. 2019-ACM-ICPC-徐州站网络赛- I. query-二维偏序+树状数组

    2019-ACM-ICPC-徐州站网络赛- I. query-二维偏序+树状数组 [Problem Description] ​ 给你一个\([1,n]\)的排列,查询\([l,r]\)区间内有多少对 ...

  8. 【新品发布】智能驾驶实车测试系统-VDAS

    智能驾驶技术的迭代研发,需要多种传感器.海量数据.海量场景的支撑.而目前多种传感器Gbit/s级别的数据同步采集.海量数据的快速分析和评估.关键场景的切片和提取,是业界公认的棘手问题. 为了解决上述的 ...

  9. js基础知识1

    本博客转自某不知名程序员 1. JavaScript基础分为三个部分: ECMAScript:JavaScript的语法标准.包括变量.表达式.运算符.函数.if语句.for语句等. DOM:操作网页 ...

  10. python中实现一个简单的进度条

    import time def progress(n,a): m = int(n / a * 100) x = int(n / a * 10) time.sleep(0.2) #只是为了让进度条明显 ...