MapReduce如何让数据完成一次旅行

大家应该知道MapReduce不仅仅是一个分布式计算的框架而且还是一种算法,常规的算法中,我们也可以使用这种模型去进行运算,也就是Mapper-Reducer过程,但是MapReduce还有很多看不见的过程,也是值得让我们去研究一下的,比如说shuffle,就是其中相当关键的一个环节,大家都知道这是混洗但是混洗的具体过程是什么,又是一个问题,因此本篇文章将会主要讲述一下MapReduce的过程。

首先在实践中这个过程中有两个关键的问题:

  • 如何给每个数据块分配Map计算任务,大家应该也都知道了每个数据块在HDFS上对应一个BlockID,那么Map如何去找到这些数据块?
  • 环境是分布式的,处在不同的服务器的Map后的数据,如何将相同的Key聚合一起发送给Reduce任务进行处理?

大家先来看一下MapReduce的整体流程图:
在这里插入图片描述

MapReduce作业启动和运行机制

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

  1. 大数据应用进程

这类进程是启动MapReduce程序的主入口。指定Map和Reduce类的位置,输入输出文件路径。然后提交给Hadoop集群的JobTracker进程。

  1. JobTracker进程

这类进程根据要处理的输入数据量,命令下面提到的Task Tracker进程启动对应数量的map和reduce进程,并管理map和reduce的任务调度与监控,管理整个作业的生命周期。Job Tracker进程在整个Hadoop集群中全局唯一,与NameNode启动在相同节点。

  1. TaskTracker进程

负责启动和管理Map进程和Reduce进程,与DataNode启动在相同的节点,并且与DataNode同时启动,并且与Job Tracker的关系形如DataNode何NameNode。

后面讲到的Yarn和Spark也是相同的架构模式
架构模式:可重复使用的架构方案。
分布式中常见的一主多从可谓是大数据领域最主要的架构模式。

接下来进一步了解一下MapReduce
在这里插入图片描述
接下来解释一下整个计算过程的流程:

  1. 应用进程JobClient将用户的作业包存储在HDFS中,将来会分发给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)和任务参数(数据块路径,文件路径,程序路径)要处理的数据在文件中的偏移量、数据块多个备份的DataNode等等,然后正式启动MapReduce进程。
  8. 进程启动之后,开始寻找jar包,先从linux上找,然后再从HDFS上找。
  9. 如果是Map进程,从HDFS读取数据,如果是Reduce进程将结果写出到HDFS。

虽然描述起来步骤很多,但是实际上自己要写的仅仅是map函数和reduce函数,其余的都被内部安排了。

MapReduce数据合并与连接机制

在MapReduce的Map输出然后输入到Reduce阶段中,有一个专门的操作叫做shuffle,那么shuffle到底是什么呢?shuffle具体过程又是怎样的呢?请看下图:
在这里插入图片描述
每个Map任务的计算结果都会写入到本地文件系统,等Map任务快要计算完成的时候,MapReduce计算框架会启动shuffle过程,在Map任务进程调用一个Partitioner接口,对Map产生的每个<key,value>进行Reduce分区选择,然后通过基本的HTTP协议发送给对应的Reduce进程。这样Map不管位于哪一个节点,都会成功的聚合。

map输出的<key,value>shuffle到哪个Reduce进程是这里的关键,它是由Partitioner来实现,MapReduce框架默认的Partitioner用key的哈希值对Reduce任务数量取模,相同的key一定会落在相同的Reduce任务ID上。从实现上来看,这样的Partitioner代码只需要一行。

public int getPartition(K2 key, V2 value, int numReduceTasks) {
      return (key.hashCode() & Integer.MAX_VALUE) % numReduceTasks;   
} 

总结

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

shuffle是分布式计算中非常神奇的存在,不管是MapReduce还是Spark,只要是大数据批处理计算,都会有这个阶段,让数据关联起来,数据的内在关系和价值才会呈现出来。同时shuffle也是MapReduce过程中最难、最消耗性能的地方。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值