《Hadoop技术内幕》读书笔记——Task运行过程分析
本文是董西成的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运行过程分析的更多相关文章
- Struts2技术内幕 读书笔记一 框架的本质
本读书笔记系列,主要针对陆舟所著<<Struts2技术内幕 深入解析Strtus2架构设计与实现原理>>一书.笔记中所用的图片若无特殊说明,就都取自书中,特此声明. 什么是框架 ...
- Struts2技术内幕 读书笔记三 表示层的困惑
表示层能有什么疑惑?很简单,我们暂时忘记所有的框架,就写一个注册的servlet来看看. index.jsp <form id="form1" name="form ...
- 深入理解linux网络技术内幕读书笔记(三)--用户空间与内核的接口
Table of Contents 1 概论 1.1 procfs (/proc 文件系统) 1.1.1 编程接口 1.2 sysctl (/proc/sys目录) 1.2.1 编程接口 1.3 sy ...
- Struts2技术内幕 读书笔记二 web开发的基本模式
最佳实践 在讨论基本模式之前,我们先说说一个词:最佳实践 任何程序的编写都得遵循一个特定的规范.这种规范有约定俗称的例如:包名全小写,类名每个单词第一个字母大写等等等等;另外还有一些需要我们严格遵守的 ...
- MySQL技术内幕读书笔记(八)——事务
事务的实现 事务隔离性由锁来实现.原子性.一致性.持久性通过数据库的redo log和undo log来完成.redo log称为重做日志,用来保证事务的原子性和持久性.undo log用来保证事 ...
- MySQL技术内幕读书笔记(七)——锁
锁 锁是数据库系统区分与文件系统的一个关键特性.为了保证数据一致性,必须有锁的介入.数据库系统使用锁是为了支持对共享资源进行并发访问,提供数据的完整性和一致性. lock与latch 使用命令 ...
- MySQL技术内幕读书笔记(六)——索引与算法之全文索引
全文索引 概述 通过索引字段的前缀进行查找,B+树索引是支持的,利用B+树索引就可以进行快速查询. SELECT * FROM blog WHERE content like 'xxx%'; ...
- MySQL技术内幕读书笔记(二)——InnoDB存储引擎
目录 InnoDB存储引擎 InnoDB存储架构 Checkpoint技术 Master Thread 工作方式 InnoDB关键特性(放一下,感觉看后面,再看总结吧) InnoDB存储引擎 Inno ...
- webkit技术内幕读书笔记 (一)
本文部分摘录自互联网. Chromeium与Chrome Chromium是Google为发展自家的浏览器Google Chrome而打开的项目,所以Chromium相当于Google Chrome的 ...
随机推荐
- Windows平台编程涉及的函数
VirtualAlloc 调用进程的虚拟地址空间 GetTickCount 返回从操作系统启动到当前所经历过的毫秒数 malloc.h内存分配函数,需要头文件malloc.h
- Python的介绍及Pycharm软件的安装
一.Python介绍 1. Python是一种解释性.面向对象.动态数据类型的高级程序设计语言. Python语言创始人是吉多.范罗苏姆:起源与1989年 2. 缺点:运行速度慢(由于是解释性语言 ...
- DOM 踩踩踩
1.如果是想给一个DOM元素添加一个伪类,可以转换为 为这个元素添加一个类名,这个类名上面绑定一个伪类. 2.append一个元素,删除掉原来的元素再进行添加.
- 《利用Python进行数据分析》笔记---第2章--1880-2010年间全美婴儿姓名
写在前面的话: 实例中的所有数据都是在GitHub上下载的,打包下载即可. 地址是:http://github.com/pydata/pydata-book 还有一定要说明的: 我使用的是Python ...
- angularjs 定时器 销毁
angular.module('app', []) .controller('ItemController', function($scope, $interval) { // store the i ...
- [Linux] find文件查找和grep文件内容查找
在使用linux时,经常需要进行文件查找.其中查找的命令主要有find和grep.两个命令是有区别的: (1)find命令:根据文件的属性进行查找,如文件名,文件大小,所有者,所属组,是否为空,访问时 ...
- postfix邮件服务器搭建02-安装篇
本文接着上文的环境,进行postfix邮件发信端和dovecot邮件收信端的部署,之后部署基于浏览器的extmail图形管理端,使管理员可以通过网页对邮件虚拟用户进行管理,对邮件服务器进行管控 1.p ...
- Linux libusb 安装及简单使用
Linux libusb 安装及简单使用 一.参考文档: . libusb1 fails do_configure task with “udev support requested but libu ...
- java 实现共享锁和排它锁
一直对多线程有恐惧,在实现共享锁和排它锁之后,感觉好了很多. 共享锁 就是查询的时候,如果没有修改,可以支持多线程查询: 排它锁 就是修改的时候,锁定共享锁,停止查询,同时,锁定排它锁,只 ...
- BZOJ2821 作诗(Poetize) 【分块】
BZOJ2821 作诗(Poetize) Description 神犇SJY虐完HEOI之后给傻×LYD出了一题: SHY是T国的公主,平时的一大爱好是作诗. 由于时间紧迫,SHY作完诗之后还要虐OI ...