Skip to content

Instantly share code, notes, and snippets.

@xcaspar
Last active August 29, 2015 14:25
Show Gist options
  • Save xcaspar/d27f78bcf2b2c0f9be87 to your computer and use it in GitHub Desktop.
Save xcaspar/d27f78bcf2b2c0f9be87 to your computer and use it in GitHub Desktop.

MapReduce任务的执行总流程

@(Hadoop)[mapreduce]

介绍

在main()函数中写入JobClient.runJob(conf),然后将程序提交到Hadoop上,一个MapReduce作业就可以在Hadoop上运行,一个作业的执行流程是:代码编写->作业配置->作业提交->Map任务的分配和执行->处理中间结果->Reduce任务的分配和执行->作业完成,而在每个任务的执行过程中,又包含输入准备->任务执行->输出结果。流程图如下: z-1437461403590.png
从图中可以看出MapReduce作业的执行可以分为11个步骤,涉及到4个独立的实体。它们在MapReduce执行过程中的主要作用是:

  • 客户端:编写MapReduce代码,配置作业,提交作业。
  • JobTracker:初始化作业、分配作业,与TaskTracker通信,协调整个作业的执行;
  • TaskTracker:保持JobTracker的通信,在分配的数据片段上执行Map或Reduce任务。
  • HDFS:保存作业的数据、配置信息等,保存作业的结果。

问题

  • Map任务后数据存放到哪? map任务将其输出写入本地硬盘,而非HDFS。是因为map的输出是中间结果,经过reduce任务处理后就没有意义了。如果该节点上运行的map任务在将map中间结果传送给reduce任务之前失败,hadoop将在另一个节点上重新运行这个map任务以再次构建map中间结果。
  • 为什么要让分片和块大小相等? 之所以让分片和块的大小相等,是因为它确保可以存储在单个节点上的最大输入块的大小。如果分片跨越两个数据块,那么对于任何一个HDFS节点,基本不可能同时存储两个数据块,因此分片中的部分数据需要通过网络传输到map任务节点。与使用本地数据运行整个map任务相比,这种方法显然效率更低。
  • Reduce数据如何传输? Reduce任务并不具有数据本地化的优势—单个reducer任务的输入通常来自于所有mapper的输出。因此,排过序的map输出需通过网络传输发送到运行reduce任务的节点。 数据在reduce端合并,然后由用户定义的reduce函数处理。reduce的输出通常存储在HDFS中以实现可靠存储。对于每个reduce输出的HDFS块,第一个副本存储在本地节点上,其他副本存储在其他机架节点中。因此,reduce的输出写入HDFS会占用网络带宽,这与正常的HDFS流水线写入的消耗一样。
  • 为什么使用合并函数(combiner)? 集群上的可用带宽限制了MapReduce作业的数量,因此最重要的是一点是尽量避免map任务和reduce任务之间的数据传输。Hadoop允许用户针对map任务的输出指定一个合并函数combiner,就像mapper和reducer一样(合并函数的规则限定了可以使用的函数类型)。合并函数的输出作为reduce函数的输入。由于合并函数是一个优化方案,所以Hadoop无法确定针对map任务输出中任意一条记录需要调用多少次合并函数。也就是说,无论调用合并函数多少次,reducer的输出结果都应一致。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment