大数据学习-WordCount运行全貌

Posted on By Vivian Sun

简介

介绍WordCount运行全貌,探讨mapper和reducer之间的关系,Hadoop的内部工作机制。

1. 启动

调用驱动中的Job.waitForCompletion()是所有行动的开始。

  • 该驱动是程序唯一一段运行在本地机器上的代码
  • 开启了本地主机和JobTracker通信。
  • JobTracker负责作业调度和执行的各个方面,是执行如何与作业管理相关的任务时的主要连接口
  • JobTracker代表我们与NameNode通信,并对存储在HDFS上的数据相关的所有交互进行管理。

2. 输入分块

HDFS通常被分成至少64MB的数据块,JobTracker会将每个数据块分配给一个map任务。

  • 这些交互发生在JobTracker接受输入数据,并确定如何将其分配给map任务的时候
  • 各分块完成了运算,JobTracker就会将它们和包含mapper与reducer类的jar文件放置在HDFS上作业专用的目录,而该路径在任务开始时将被传递给每个任务

3. 任务分配

JobTracker确定了所需的map任务数,它就会检查集群中的主机数,正在运行的TaskTracker数以及可并发执行的map任务数(用户自定义的配置变量)

  • JobTracker会尝试定义一个执行计划,使TaskTracker尽可能处理位于相同物理主机上的数据块。
  • 或者即使做不到这点,TaskTracker至少处理一个位于相同硬件机架中的数据块
  • 数据局部性优化是Hadoop能高效处理巨大数据集的一个关键原因。
  • 默认情况下,每个数据块被复制到三台不同的主机
  • 本地处理大部分数据块的任务/主机计划比起初预想的可能性更高。

4. 启动任务

每个TaskTracker开启一个独立Java虚拟机来执行任务。

  • 虽然增加了启动时间损失,但它可以隔离运行map或reducer所引发的问题和TaskTracker
  • 而且可以配置成在随后的任务之间共享
  • 如果集群有足够的能力一次性执行所有的任务,它们将会被全部启动,并获得它们将要处理的分块数据和作业jar文件
  • 每个TaskTracker随后将分块复制到本地文件系统
  • 如果任务数超过了集群能力,JobTracker将维护一个挂起任务队列,并在节点完成最初分配的map任务后,将挂起任务分配给节点

5. 不断监视JobTracker

JobTracker等待TaskTracker执行所有的mapper和reducer。不断地与TaskTracker交换心跳和状态下次,查找进度或问题的证据。

JobTracker从整个作业执行过程的所有任务中收集指标,其中一些指标是Hadoop提供的,还有一些是map和reduce任务的开发人员制定。

6. mapper的输入

WordCount实例驱动类使用TextInputFormat指定了输入文件的格式和结构。因此Hadoop会把输入文件看做以行号为键并以改行内容为值的文本

7. mapper的执行

依据作业的配置方式,mapper接收到的键/值对分别是相应行在文件中的偏移量以及该行内容。

  • WordCount实例类的mapper方法舍弃了键并使用标准的java string类的split方法将每行文本内容拆分成词(使用正则表达式或StringTokenizer可以更好的短词)
  • 针对每个单独的词,mapper输出由单词本身组成的键和值

8. mapper的输出和reducer的输入

mapper的输出是一系列形式为(word,1)的键值对

  • 键值对并不会直接传给reducer,中间还有一个shuffle阶段,这也是许多MapReduce奇迹发生的地方

9. 分块

Reduce接口的隐性保证之一是,与给定键值相关的所有值都会被提交到同一个reducer。

  • 一个集群中运行着多个reduce任务,每个mapper的输出必须被分块,使其分别传入相应的各个reducer。这些分块文件保存在本地节点的文件系统
  • 集群中的reduce任务数并不像mapper数量一样是动态的,我们可以在作业提交阶段指定reduce任务数。因此每个TaskTracker就知道集群中有多少个reduce,并据此得知mapper输出应切分为多少块

10. 可选分块函数

默认情况下,Hadoop将对输出的键进行哈希运算,从而实现分块。

  • 功能有org.apache.hadoop.mapreduce.lib.artition包中的HashPartitioner类实现。
  • 用户可以自定义Partitioner子类,实现针对具体应用的分块逻辑。特别是标准哈希导致数据分布不均匀时。

11. reducer类的输出

reducer的TaskTracker从JobTracker接收更新,指明集群中那些节点承载着map的输出分块。

之后TaskTracker从各个节点获取分块,并将它们合并成一个文件反馈给reducer任务处理

12. reducer类的执行

WordCountReducer类很简单,针对每个词实现词频统计。最后输出(word, count)

  • 通常reducer的调用次数小于mapper的调用次数。如果有非常严格的性能要求,可以采用任何有利于提高性能的措施
  • 先期MapReduce对数据集执行标准化或清理策略

13. reducer类的输出

WordCount最后输出是(word, count),这些数据将被输出到驱动程序指定的输出路径下的分块文件中,并将使用指定的OutputFormat对其进行格式化。

  • 每个reducer任务写入一个以part-r-nnnnn为文件名的文件,其中nnnnn从00000开始并逐步递增。

14. 关机

一旦成功完成所有任务,JobTracker向客户端输出作业的最终状态,以及作业运行过程中一些比较重要的计数器集合。

  • 完整的作业和任务历史记录存储在每个节点的日志路径中,通过JobTracker节点的50030端口可以访问

小结

流程图

Reference