本文是董西成的Hadoop技术内幕一书的读书章节总结。

第八章 Task运行过程分析

所有Task需要周期性地向TaskTracker汇报最新进度和计数器值,而这正是由Reporter组件实现的,其中Reporter汇报的信息中包含两个部分:任务执行进度以及任务计数器值。

任务执行进度

hadoop采用简单的线性模型计算每个阶段的进度值,对于Map Task而言,作为一个大阶段不再分解,一般实用RecordReader中的getProgress()方法划定执行进度;对于Reduce Task而言,可以分成三个阶段:Shuffle,Sort和Reduce,每个阶段占任务总进度的1/3。

对于任务的Reporter而言,并不会总是每隔一段时间汇报进度和计数器值,而是仅当发现以下两种情况之一时才会汇报:

  • 任务执行进度发生变化;
  • 任务的某个计数器值发生变化;

某个时间间隔内,如果任务执行进度和计数器值均未发生变化,则Task只会RPC调用ping函数探测TaskTracker是否alive,如果一直发生这种情况,TaskTracker认为这个任务处于悬挂状态,直接kill掉。因此我怀疑我们的任务被杀,也是因为这个原因:

 
AttemptID:attempt_1412848624484_2765_m_000032_0 Timed out after 1200 secsContainer killed by the ApplicationMaster. Container killed on request. Exit code is 143

为了避免这个问题,可以采用下面两种方法:

  • 每隔一段时间调用一次TaskReporter.progress()函数,告诉TaskTracker自己仍然活着;
  • 增大任务超时参数mapreduce.task.timeout参数(默认10分钟,用毫秒表示)。

任务计数器

任务计数器(Counter)是hadoop提供的,用于实现跟踪任务运行进度的全局计数功能,用户可以在自己的应用程序中添加计数器,计数器包括两个部分<name, value>,name表示计数器名称,value表示计数器值,hadoop规定一个作业最多包含120个计数器(修改mapreduce.job.counters.limit),50个计数器组。

Job的计数器分成两类:内置计数器和用户自定义计数器。

用户可以自定义计数器来进行MR程序的一些数据的统计,在老版本中需要自定义一个枚举,新版本中只需要提供对应的字符串变量即可:

reporter.getCounter(groupName, counterName).increment(1);
reporter.incrCounter(groupName, counterName, 1);

Map Task整体流程

Map Task总共分成5个阶段:

  • Read阶段:通过用户编写的RecordReader,从输入InputSplit中解析出一个key/value;
  • Map阶段:将解析出来的key/value交给用户编写的map函数处理,并产生一系列新的key/value;
  • Collect阶段:当Map阶段处理完数据之后,一般会调用OutputCollector.collect()输出结果,该函数内部会将生成的key/value通过Partitioner分片,写入一个环形缓冲区中;
  • Spill阶段:当缓冲区满之后,MapReduce会将数据写到本地磁盘中,生成临时文件,在将数据写入本地磁盘之前,先要对数据进行一次本地排序,并在必要时对数据进行合并,压缩等操作;
  • Combine阶段:当所有的数据处理完成后,Map Task会对所有临时文件进行一次合并,确保最终只会生成一个数据文件。


 

Reduce Task整体流程

Reduce Task也分为5个阶段:

  • Shuffle阶段:也称为Copy阶段,Reduce Task从各个Map Task上远程拷贝一片数据,并针对某一片数据,如果其大小超过一点阈值,写到磁盘上,否则直接在内存中操作;
  • Merge阶段:在远程拷贝数据的同时,Reduce Task启动了两个后台线程对内存和磁盘上的文件进行合并,防止内存实用过多或磁盘上的文件过多;
  • Sort阶段:用户编写的Reduce函数输入数据是按照key进行聚集的一组数据,与Map的数据有所不同。为了将key相同的数据聚集在一起,hadoop会先进行排序。由于事先在Map Task中的输出数据已经局部有序,因此Reduce Task只需要再对所有数据进行一次归并排序即可;
  • Reduce阶段:该阶段中,Reduce Task将每组数据依次交给用户编写的reduce函数处理;
  • Write阶段:OutputCollector.collect(key, value)会将计算结果写到HDFS上。


 

MapReduce的排序

排序是MapReduce框架中最重要的操作之一,Map Task和Reduce Task均会对数据按照key进行排序,这种排序操作属于Hadoop的默认行为,任何应用程序中的数据均会被排序。

Map Task会讲处理的结果暂时放到一个缓冲区中,当缓冲区使用率达到一定的阀值之后,对数据进行一次排序(内存中),并将这些数据以IFile的文件形式写到磁盘上。当全部的数据处理完成后,会对磁盘上的所有文件进行一次合并并排序成一个大的有序文件。

Reduce Task从每个Map Task上远程拷贝相应的数据文件,如果文件大小超过一定的阈值,放到磁盘上,否则暂时放到内存中,如果磁盘上的文件数目达到一定阈值,进行一次合并以声称一个更大的文件。当所有的数据都拷贝完成后,Reduce Task会统一对内存和磁盘上的所有数据进行一次合并。

Hadoop中的文件合并采用了多轮递归合并的方法,每轮选取最小的前io.sort.factor个文件进行合并,并将产生的文件重新加入待合并列表中,直到剩下的文件数量小于io.sort.factor。

在合并的过程中,采用的方式为小顶堆,在小顶堆中选取io.sort.factor,在排序完成后,将结果继续放到该小顶堆中,继续直到剩下的数量小于io.sort.factor,排序到只剩下一个文件。

Reduce端的Shuffle和Merge阶段

Reduce Task中Shuffle阶段和Merge阶段是并行进行的,当远程拷贝数据量达到一定的阈值后,便会出发相应的合并线程对数据进行合并,这个阶段也可以进一步划分为三个子阶段:

  • 准备运行完成的Map Task列表,GetMapEventsThread线程周期性地通过RPC从TaskTracker获取已完成的Map Task列表,为防止网络热点,Reduce Task通过对所有TaskTracker Host进行混洗操作以打乱数据拷贝顺序,并将调整后的Map Task输出数据位置保存到scheduleCopies列表中。
  • 远程拷贝数据,Reduce Task同时启动多个MapOutputCopier线程,这些线程从scheduleCopies列表中获取Map Task输出位置,并通过HTTP Get远程拷贝数据,对于获取的数据分片,如果大小超过一定阈值,则存放到磁盘上,否则直接放到内存中。
  • 合并内存文件和磁盘文件,为了防止内存或者磁盘上的文件过多,Reduce Task启动两个线程分别对磁盘和内存中的文件进行合并。

Reduce端的Sort和Reduce阶段

所有的数据拷贝完成后,数据可能放在内存中或者磁盘上,还不能将数据直接交给用户编写的reduce函数处理,根据MapReduce的语义,Reduce Task需将key值相同的数据聚集在一起,并按组将数据交给reduce函数处理。

为此,Hadoop采用了基于排序的数据聚集策略,各个Map Task已经事先对自己的输出分派呢进行了局部排序,因此,Reduce Task只需要进行一次归并排序即可保证数据整体有序。为了提高效率,Hadoop将Sort阶段和Reduce阶段并行化。

在Sort阶段,Reduce Task为内存和磁盘中的文件建立了小顶堆,保存了指向该小顶堆节点的迭代器,且该迭代器保证了磁盘上的文件数目小于io.sort.factor, 当Reduce阶段开始时,内存中数据量小于最大可用内存(JVM MaxHeapSize)的mapred.job.reduce.input.buffer.precent。

在Reduce阶段,Reduce Task不断地移动迭代器,以将key相同的数据顺次地交给reduce函数处理,期间移动迭代器的过程实际上就是不断调整小顶堆的过程,这样Sort,Reduce就可以并行执行。

《Hadoop技术内幕》读书笔记——Task运行过程分析的更多相关文章

  1. Struts2技术内幕 读书笔记一 框架的本质

    本读书笔记系列,主要针对陆舟所著<<Struts2技术内幕 深入解析Strtus2架构设计与实现原理>>一书.笔记中所用的图片若无特殊说明,就都取自书中,特此声明. 什么是框架 ...

  2. Struts2技术内幕 读书笔记三 表示层的困惑

    表示层能有什么疑惑?很简单,我们暂时忘记所有的框架,就写一个注册的servlet来看看. index.jsp <form id="form1" name="form ...

  3. 深入理解linux网络技术内幕读书笔记(三)--用户空间与内核的接口

    Table of Contents 1 概论 1.1 procfs (/proc 文件系统) 1.1.1 编程接口 1.2 sysctl (/proc/sys目录) 1.2.1 编程接口 1.3 sy ...

  4. Struts2技术内幕 读书笔记二 web开发的基本模式

    最佳实践 在讨论基本模式之前,我们先说说一个词:最佳实践 任何程序的编写都得遵循一个特定的规范.这种规范有约定俗称的例如:包名全小写,类名每个单词第一个字母大写等等等等;另外还有一些需要我们严格遵守的 ...

  5. MySQL技术内幕读书笔记(八)——事务

    事务的实现 ​ 事务隔离性由锁来实现.原子性.一致性.持久性通过数据库的redo log和undo log来完成.redo log称为重做日志,用来保证事务的原子性和持久性.undo log用来保证事 ...

  6. MySQL技术内幕读书笔记(七)——锁

    锁 ​ 锁是数据库系统区分与文件系统的一个关键特性.为了保证数据一致性,必须有锁的介入.数据库系统使用锁是为了支持对共享资源进行并发访问,提供数据的完整性和一致性. lock与latch ​ 使用命令 ...

  7. MySQL技术内幕读书笔记(六)——索引与算法之全文索引

    全文索引 概述 ​ 通过索引字段的前缀进行查找,B+树索引是支持的,利用B+树索引就可以进行快速查询. SELECT * FROM blog WHERE content like 'xxx%'; ​ ...

  8. MySQL技术内幕读书笔记(二)——InnoDB存储引擎

    目录 InnoDB存储引擎 InnoDB存储架构 Checkpoint技术 Master Thread 工作方式 InnoDB关键特性(放一下,感觉看后面,再看总结吧) InnoDB存储引擎 Inno ...

  9. webkit技术内幕读书笔记 (一)

    本文部分摘录自互联网. Chromeium与Chrome Chromium是Google为发展自家的浏览器Google Chrome而打开的项目,所以Chromium相当于Google Chrome的 ...

随机推荐

  1. L160

    In the Soviet Union several cases have been reported recently of people whocan read and detect colou ...

  2. Mac工具整理

    记录一下这两年来使用Mac的一些很好的工具: 1.offic,mac的office还是很强大的,比openoffice要好很多,更比WPS要好. 2.Toad连接数据库用的,一般用来连接Oracle. ...

  3. Android程序员学WEB前端(7)-CSS(2)-伪类字体文本背景边框-Sublime

    转载请注明出处:http://blog.csdn.net/iwanghang/article/details/76618373 觉得博文有用,请点赞,请评论,请关注,谢谢!~ 伪类: <!DOC ...

  4. 《gradle 用户指南中文版》 第一部分、关于Gradle

    第一部分.关于Gradle 目录1.介绍1.1 关于本用户指南2.概述2.1 特性2.2 为什么选择Groovy? 上一页  |  目录  |  下一页

  5. EasyPusher/EasyDarwin支持H.265 RTSP/RTP直播推流与分发播放

    前言描述 随着大屏时代和高清时代的到来,人们已经不再满足于VGA.CIF这种小分辨率了,取而代之的是720P.1080P.4K级的视频传输,虽然我们国家的基础带宽一直在上升,但普遍情况下,传输高清视频 ...

  6. JAVA怎么在函数内改变传入的值

    public class TestInt { public int aa(int i) { return i+4; } public static void main(String [] args) ...

  7. python常用模块之xml模块

    python常用模块之xml模块 xml是实现不同语言或程序之间进行数据交换的协议,跟json差不多,但json使用起来更简单,不过,在json还没诞生的年代,大家都是使用xml,目前很多传统公司的系 ...

  8. I.MX6 linux eGalaxTouch 自动获取设备节点

    I.MX6 linux eGalaxTouch 自动获取设备节点 \\\\\\\\\\\\\\-*- 目录 -*-///////////// | 一. 需求: | 二. /proc/bus/input ...

  9. 【剑指offer】找出数组中任意重复的数字(不修改数组),C++实现

    原创博文,转载请注明出处! # 题目 在一个长度为n+1的数组里的所有数字都在1~n的范围内,所以数组中至少有一个数字是重复的.请找出数组中任意一个重复的数字,但不能修改输入的数组.例如,如果输入长度 ...

  10. 【剑指offer】数组中出现次数超过数组长度一半的数字,C++实现

    原创博文,转载请注明出处! # 题目 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于数字2在数组中出现了5次,超过 ...