admin 管理员组

文章数量: 887017

MapReduce 编程模型将大数据计算过程切分为 Map 和 Reduce 两个阶段,在 Map 阶段为每个数据块分配一个 Map 计算任务,然后将所有 map 输出的 Key 进行合并,相同的 Key 及其对应的 Value 发送给同一个 Reduce 任务去处理。通过这两个阶段,工程师只需要遵循 MapReduce 编程模型就可以开发出复杂的大数据计算程序。

那么这个程序是如何在分布式集群中运行起来的呢?MapReduce 程序又是如何找到相应的数据并进行计算的呢?

答案就是需要 MapReduce 计算框架来完成。

两个关键问题需要处理

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

这两个关键问题对应的就是图中的两处“MapReduce 框架处理”,具体来说,它们分别是 MapReduce 作业启动和运行,以及 MapReduce 数据合并与连接。

MapReduce 作业启动和运行机制

以 Hadoop 1 为例,MapReduce 运行过程涉及三类关键进程。

1.大数据应用进程。 这类进程是启动 MapReduce 程序的主入口,主要是指定 Map 和 Reduce 类、输入输出文件路径等,并提交作业给 Hadoop 集群,也就是下面提到的 JobTracker 进程。这是由用户启动的 MapReduce 程序进程,比如我们上期提到的 WordCount 程序。

2.JobTracker 进程。 这类进程根据要处理的输入数据量,命令下面提到的 TaskTracker 进程启动相应数量的 Map 和 Reduce 进程任务,并管理整个作业生命周期的任务调度和监控。这是 Hadoop 集群的常驻进程,需要注意的是,JobTracker 进程在整个 Hadoop 集群全局唯一。

3.TaskTracker 进程。 这个进程负责启动和管理 Map 进程以及 Reduce 进程。因为需要每个数据块都有对应的 map 函数,TaskTracker 进程通常和 HDFS 的 DataNode 进程启动在同一个服务器。也就是说,Hadoop 集群中绝大多数服务器同时运行 DataNode 进程和 TaskTracker 进程。

具体来看,MapReduce 的主服务器就是 JobTracker,从服务器就是 TaskTracker。还记得我们讲 HDFS 也是主从架构吗,HDFS 的主服务器是 NameNode,从服务器是 DataNode。后面会讲到的 Yarn、Spark 等也都是这样的架构,这种一主多从的服务器架构也是绝大多数大数据系统的架构方案。

整体流程如下:

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

2.应用程序提交 job 作业给 JobTracker。

3.JobTracker 根据作业调度策略创建 JobInProcess 树,每个作业都会有一个自己的 JobInProcess 树。

4.JobInProcess 根据输入数据分片数目(通常情况就是数据块的数目)和设置的 Reduce 数目创建相应数量的 TaskInProcess。

5.TaskTracker 进程和 JobTracker 进程进行定时通信。

6.如果 TaskTracker 有空闲的计算资源(有空闲 CPU 核心),JobTracker 就会给它分配任务。分配任务的时候会根据 TaskTracker 的服务器名字匹配在同一台机器上的数据块计算任务给它,使启动的计算任务正好处理本机上的数据,以实现我们一开始就提到的“移动计算比移动数据更划算”。

7.TaskTracker 收到任务后根据任务类型(是 Map 还是 Reduce)和任务参数(作业 JAR 包路径、输入数据文件路径、要处理的数据在文件中的起始位置和偏移量、数据块多个备份的 DataNode 主机名等),启动相应的 Map 或者 Reduce 进程。

8.Map 或者 Reduce 进程启动后,检查本地是否有要执行任务的 JAR 包文件,如果没有,就去 HDFS 上下载,然后加载 Map 或者 Reduce 代码开始执行。

9.如果是 Map 进程,从 HDFS 读取数据(通常要读取的数据块正好存储在本机);如果是 Reduce 进程,将结果数据写出到 HDFS。

MapReduce 数据合并与连接机制

MapReduce 计算真正产生奇迹的地方是数据的合并与连接。

几乎所有的大数据计算场景都需要处理数据关联的问题,像 WordCount 这种比较简单的只要对 Key 进行合并就可以了,对于像数据库的 join 操作这种比较复杂的,需要对两种类型(或者更多类型)的数据根据 Key 进行连接。

在 map 输出与 reduce 输入之间,MapReduce 计算框架处理数据合并与连接操作,这个操作有个专门的词汇叫 shuffle

shuffle的理解

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


每个 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 上。从实现上来看的话,这样的 Partitioner 代码只需要一行。


 /** Use {@link Object#hashCode()} to partition. */ 
public int getPartition(K2 key, V2 value, int numReduceTasks) { 
    return (key.hashCode() & Integer.MAX_VALUE) % numReduceTasks; 
 }

小结

MapReduce 编程相对说来是简单的,但是 MapReduce 框架要将一个相对简单的程序,在分布式的大规模服务器集群上并行执行起来却并不简单。理解 MapReduce 作业的启动和运行机制,理解 shuffle 过程的作用和实现原理,对你理解大数据的核心原理,做到真正意义上把握大数据、用好大数据作用巨大。

思考题

互联网应用中,用户从手机或者 PC 上发起一个请求,请问这个请求数据经历了怎样的旅程?完成了哪些计算处理后响应给用户?

来自极客时间精选留言,本思考题比较开放

大神1

课后题,有点意思,可以从很多维度来答,我猜一下:
1:这个请求在用户的电脑上,要经过浏览器应用程序的进程,从用户态内存空间写到内核态内存空间,然后经过DMA控制把信息写到网卡,网卡再把信息发送出去,信息发出去的时候就会从ISO七层网络通信协议,从上往下一层打包加信息,直到最低层编程光或电信号
2:电信号在传输的过程中会经过路由器,电缆通信线路,我们访问的是域名,还有经过域名解析,定位到网络中的具体机器,然后经过局域网、广域网、局域网
3:到了对应的局域网络后,会过网关,过负载均衡器,到应用服务器,到具体的应用程序进程中,然后进行业务逻辑的处理,可能会查询数据库或者缓存,然后进行计算,计算完了就返回,过程和来时相似

大神2

1.数据从PC/Mobile端发动给服务器端
2.服务器端收到数据后在分布式集群下会进入到某个Server端,数据经过一系列的业务操作后可能会被记录下来
3.这些记录下来的数据会以文件形式存放于某个固定位置
4.数据推送工具可将这些固定位置的文件推送到大数据平台
5.大数据平台的Map Reduce框架会根据程序应用主动读取数据作为Map/Reduce的数据输入
6.大数据平台清晰完数据后以文件形式输出
7.服务器端去大数据平台存放文件的位置获取文件,并进行解析入库。
8.最终,数据以图形形式展示在报告上。

第4步应该不需要,记录可以直接到大数据平台,或者是移动计算而不是移动数据。7步也不需要,数据平台计算结果可直接展示报告。

该笔记摘录自极客时间课程
《从0开始学大数据》

本文标签: 框架 数据 MapReduce