MapReduce 既是一个编程模型,又是一个计算框架.

为什么这样说呢?开发人员必须基于 MapReduce 编程模型进行编程开发,然后将程序通过 MapReduce 计算框架分发到 Hadoop 集群中运行。我们先看一下作为编程模型的 MapReduce。

为什么说 MapReduce 是一种非常简单又非常强大的编程模型?

简单在于其编程模型只包含 Map 和 Reduce 两个过程,map 的主要输入是一对 值,经过 map 计算后输出一对 值;然后将相同 Key 合并,形成,再将这个 输入 reduce,经过计算输出零个或多个 对。

同时,MapReduce 又是非常强大的,不管是关系代数运算(SQL 计算),还是矩阵运算(图计算),大数据领域几乎所有的计算需求都可以通过 MapReduce 编程来实现。

MapReduce 编程模型的主要计算过程和原理

image.png
以上就是 MapReduce 编程模型的主要计算过程和原理,但是这样一个 MapReduce 程序要想在分布式环境中执行,并处理海量的大规模数据,还需要一个计算框架,能够调度执行这个 MapReduce 程序,使它在分布式的集群中并行运行,而这个计算框架也叫 MapReduce。
所以,当我们说 MapReduce 的时候,可能指编程模型,也就是一个 MapReduce 程序;也可能是指计算框架,调度执行大数据的分布式计算。

MapReduce 的计算框架是如何运作的?

在实际生产过程中,这个过程有两个关键的问题需要处理

  1. 如何为每个数据块分配一个 Map 计算任务,也就是代码是如何发送到数据块所在服务器的,发送后是如何启动的,启动以后如何知道自己需要计算的数据在文件什么位置(BlockID 是什么)。
  2. 处于不同服务器的 map 输出的 ,如何把相同的 Key 聚合在一起发送给 Reduce 任务进行处理。

那么这两个关键问题对应在 MapReduce 计算过程的哪些步骤呢?你可以看到下图中标红的两处,这两个关键问题对应的就是图中的两处“MapReduce 框架处理”,具体来说,它们分别是 MapReduce 作业启动和运行,以及MapReduce 数据合并与连接。
image.png

MapReduce 作业启动和运行机制

一张图了解整个流程
image.png

名词解释:

  1. 大数据应用进程** **:这类进程是启动 MapReduce 程序的主入口,主要是指定 Map 和 Reduce 类、输入输出文件路径等,并提交作业给 Hadoop 集群。
  2. JobTracker 进程** :**这类进程根据要处理的输入数据量,命令下面提到的 TaskTracker 进程启动相应数量的 Map 和 Reduce 进程任务,并管理整个作业生命周期的任务调度和监控。这是 Hadoop 集群的常驻进程,需要注意的是,JobTracker 进程在整个 Hadoop 集群全局唯一。
  3. TaskTracker 进程 : 这个进程负责启动和管理 Map 进程以及 Reduce 进程。因为需要每个数据块都有对应的 map 函数,TaskTracker 进程通常和 HDFS 的 DataNode 进程启动在同一个服务器。也就是说,Hadoop 集群中绝大多数服务器同时运行 DataNode 进程和 TaskTracker 进程。

    关系:

    JobTracker进程和TaskTracker进程是主从关系,主服务器通常只有一台,从服务器可能有上百千万台,所有从服务器听从主服务器的控制和安排。主服务器负责为应用程序分配服务器资源以及作业执行的调度。

    整个流程呢

  4. 应用进程 JobClient 将用户作业 JAR 包存储在 HDFS 中,将来这些 JAR 包会分发给 Hadoop 集群中的服务器执行 MapReduce 计算。

  5. 应用程序提交 job 作业给 JobTracker。
  6. JobTracker 根据作业调度策略创建 JobInProcess 树,每个作业都会有一个自己的 JobInProcess 树。
  7. JobInProcess 根据输入数据分片数目(通常情况就是数据块的数目)和设置的 Reduce 数目创建相应数量的 TaskInProcess。
  8. TaskTracker 进程和 JobTracker 进程进行定时通信。
  9. 如果 TaskTracker 有空闲的计算资源(有空闲 CPU 核心),JobTracker 就会给它分配任务。分配任务的时候会根据 TaskTracker 的服务器名字匹配在同一台机器上的数据块计算任务给它,使启动的计算任务正好处理本机上的数据,以实现我们一开始就提到的“移动计算比移动数据更划算”。
  10. TaskTracker 收到任务后根据任务类型(是 Map 还是 Reduce)和任务参数(作业 JAR 包路径、输入数据文件路径、要处理的数据在文件中的起始位置和偏移量、数据块多个备份的 DataNode 主机名等),启动相应的 Map 或者 Reduce 进程。
  11. Map 或者 Reduce 进程启动后,检查本地是否有要执行任务的 JAR 包文件,如果没有,就去 HDFS 上下载,然后加载 Map 或者 Reduce 代码开始执行。
  12. 如果是 Map 进程,从 HDFS 读取数据(通常要读取的数据块正好存储在本机);如果是 Reduce 进程,将结果数据写出到 HDFS。

    小结

    通过这样一个计算旅程,MapReduce 可以将大数据作业计算任务分布在整个 Hadoop 集群中运行,每个 Map 计算任务要处理的数据通常都能从本地磁盘上读取到。其实,你要做的仅仅是编写一个 map 函数和一个 reduce 函数就可以了,根本不用关心这两个函数是如何被分布启动到集群上的,也不用关心数据块又是如何分配给计算任务的。

    MapReduce 数据合并与连接机制

    MapReduce 计算真正产生奇迹的地方是数据的合并与连接
    在 map 输出与 reduce 输入之间,MapReduce 计算框架处理数据合并与连接操作,这个操作有个专门的词汇叫shuffle

    what is shuffle ?

image.png

每个 Map 任务的计算结果都会写入到本地文件系统,等 Map 任务快要计算完成的时候,MapReduce 计算框架会启动 shuffle 过程,在 Map 任务进程调用一个 Partitioner 接口,对 Map 产生的每个 ; 进行 Reduce 分区选择,然后通过 HTTP 通信发送给对应的 Reduce 进程。这样不管 Map 位于哪个服务器节点,相同的 Key 一定会被发送给相同的 Reduce 进程。Reduce 任务进程对收到的 ; 进行排序和合并,相同的 Key 放在一起,组成一个 ; 传递给 Reduce 执行。
map 输出的 shuffle 到哪个 Reduce 进程是这里的关键,它是由 Partitioner 来实现,MapReduce 框架默认的 Partitioner 用 Key 的哈希值对 Reduce 任务数量取模,相同的 Key 一定会落在相同的 Reduce 任务 ID 上。

小结

分布式计算需要讲不同的服务器上相关的数据合并到一起,进行下一步计算,这就是shuffle。