Hadoop大数据原理(3) - 分布式计算框架MapReduce

1. 大数据的通用计算

  Hadoop出现前就已经有了分布式计算,那个时候的分布式计算是专用的系统,只能专门处理某一类计算,比如进行大规模数据的排序。这样的系统无法复用到其他的大数据计算场景,每种应用都需要开发与维护专门的系统,通用性不够。

  直到Hadoop MapReduce的出现,使得大数据计算通用编程成为可能。我们只要遵循MapReduce编程模型,只需投入经历编写业务处理的逻辑代码,就可以运行在Hadoop分布式集群上,无需关心分布式计算是如何完成的。

2 MapReduce编程模型

  大数据计算的核心思想是尽可能的通过移动计算来代替移动数据,所以Hadoop大数据计算使用了MapReduce的编程模型。

  虽然MapReduce编程模型不是Hadoop的原创,但是Google将Hadoop和MapReduce编程模型用在大数据上面,把很多看似复杂的机器学习、数据挖掘、SQL处理等大数据都变得更加的简单和通用了。

  MapReduce编程模型只包含了Map和Reduce这2个过程:

  • Map主要输入键值对<key,value>,经过Map计算后也输出一对<key,value>
  • Reduce输入<key,value集合>,经过计算输出0个或多个<key,value>

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

  下面通过词频统计的示例来讲解MapReduce的计算过程。

原始数据
Hello World
Bye World
Hello Hadoop
Bye Hadoop

  将以上数据,进行MapReduce计算:

  1. 进行Map,针对每个单词输出1个<word,1>这样的键值对;
    • <Hello,1>, <World,1>
    • <Bye,1>, <World,1>
    • <Hello,1>, <Hadoop,1>
    • <Bye,1>, <Hadoop,1>
  2. Map中相同的<word,1>搜集起来,形成<word,<1,1,1...>>这样的<key,value集合>数据;
    • <Hello, <1,1>>, <World, <1,1>>, <Bye, <1,1>>, <Hadoop, <1,1>>
  3. 进行Reduce,将Map结果的<key,value集合>数据输入,计算过程是,将这个集合里的1求和,再将单词(word)和这个和(sum)组成一个<key,value>,也就是<word,sum>的输出。每一个输出就是一个单词和它的词频统计总和。
    • <Hello, 2>, <World, 2>, <Bye, 2>, <Hadoop, 2>

  看到这里,实际上这个思路和传统应用开发并无差别。

  在实际的大数据场景下,Map会针对一部分数据进行计算,将一个大数据切分成很多块,MapReduce计算框架会为每个数据库分配1个Map函数进行计算,实现大数据的分布式计算。

  为了更好的理解,假设有2个数据块的文本需要进行词频统计,MapReduce计算过程如下:

MapReduce过程-2个分片

3. MapReduce计算框架

  上面的MapReduce程序要想在分布式环境中执行,并处理海量的大规模数据,还需要一个计算框架,能够调度执行这个MapReduce程序,使它在分布式的集群中并行运行,而这个计算框架也叫MapReduce。

  这个过程中有两个关键问题需要处理:

  1. 如何为每个数据块分配一个Map计算任务,包括:代码是如何发送到数据块所在服务器的,发送后是如何启动的,启动以后如何知道自己需要计算的数据在文件什么位置(BlockID如何获取)。

  2. 处于不同服务器的Map输出的<key,value>,如何把相同的key聚合在一起发送给Reduce任务进行处理。

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

3.1 三类关键进程

  下面先对MapReduce的3类关键进程进行介绍,便于后面的理解。

大数据应用进程

  它是启动MapReduce程序的主入口,主要是指定Map和Reduce类、输入输出文件路径等,并提交作业给Hadoop集群,也就是下面提到的JobTracker进程,这是由用户启动的 MapReduce 程序进程。

JobTracker进程

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

TaskTracker进程

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

  从以上介绍,我们能够看出MapReduce依旧是主从架构,主服务器就是JobTracker,而从服务器就是TaskTracker。

3.2 作业启动和运行机制

  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读取数据(要读取的数据块通常存储在本机);

  10. 如果是Reduce进程,将结果数据写出到HDFS;

3.3 数据合并与连接机制

  在第二章节WordCount的例子中,想要统计相同单词在所有输入数据中出现的次数,而一个Map只能处理一部分数据,一个热门单词几乎会出现在所有的Map中,这意味着同一个单词必须要合并到一起进行统计才能得到正确的结果。

  像WordCount这种比较简单的只要对Key进行合并就可以了,对于像数据库的join操作这种比较复杂的,需要对两种类型(或者更多类型)的数据根据Key进行连接。

shuffle的过程

  在Map输出与Reduce输入之间,MapReduce计算框架处理数据合并与连接操作,这个操作就叫做shuffle。

  每个Map任务的计算结果都会写入到本地文件系统,等Map任务快要计算完成的时候,MapReduce计算框架会启动shuffle过程,在Map任务进程调用一个Partitioner接口,对Map产生的每个<key,value>进行Reduce分区选择,然后通过HTTP通信发送给对应的Reduce进程。

  不管Map位于哪个服务器节点,相同的Key一定会被发送给相同的Reduce进程。Reduce任务进程对收到的<key,value>进行排序和合并,相同的Key放在一起,组成一个<key,value集合>传递给Reduce执行。

  MapReduce框架默认的Partitioner用Key的哈希值对Reduce任务数量取模,相同的Key一定会落在相同的Reduce任务ID上。

  我们重新定一下什么是shuffle,分布式计算要将不同服务器上的相关数据合并到一起进行下一步计算,这就是shuffle。shuffle也是整个MapReduce过程中最难、最消耗性能的地方。

猜你喜欢

转载自blog.csdn.net/initiallht/article/details/124720375