正常情况下,我们都是启动Hadoop任务的方式大概就是通过hadoop jar命令(或者写在shell中),事实上运行的hadoop就是一个包装的.sh,下面就是其中的最后一行,表示在其中执行一个java命令,调用hadoop的一些主类,同时配置一些hadoop的相关CLASSPATH,OPTS等选项:
 
exec "$JAVA" $JAVA_HEAP_MAX $HADOOP_OPTS $CLASS "$@"
 
当使用hadoop jar时,调用的$CLASS是下面的类型:
 
org.apache.hadoop.util.RunJar
 
而通过hadoop jar调用的主类,必须满足条件:
 
1,其中有main方法,类似下面的定义:
public static void main(String[] args) throws Exception {
int result = ToolRunner.run(new ThisClass(), args);
System.exit(result);
}
 
2. ToolRunner中的的类需要有如下签名:
 
extends Configured implements Tool
 
并实现其中的public int run方法,在进行必要的hadoop job构造后,执行job的方法,同步等待执行结果并返回即可。
 
boolean success = job2.waitForCompletion(true);
 
大体的过程如下,以前也没有对整个过程进行质疑,直到我们有新的需要,在其他的客户端(java,而不是shell中)启动MapReduce任务,顺带好好看了这个函数waitForCompletion...
public boolean waitForCompletion(boolean verbose
) throws IOException, InterruptedException,
ClassNotFoundException {
if (state == JobState.DEFINE) {
submit();
}
if (verbose) {
monitorAndPrintJob();
} else {
// get the completion poll interval from the client.
int completionPollIntervalMillis =
Job.getCompletionPollInterval(cluster.getConf());
while (!isComplete()) {
try {
Thread.sleep(completionPollIntervalMillis);
} catch (InterruptedException ie) {
}
}
}
return isSuccessful();
}
 
读完源码后发现,其实这个方法主要的目的就是看一下当前job的状态,如果没有提交,那么就执行submit操作(同步)将其提交到集群上。传递的参数verbose,如果是true,就是表示需要检测并打印job的相关信息(使用LOG.info()来打印到console中);否则,就等待任务的complete,反正这是个同步的操作;我们如果不需要监测任务的执行状态,仅仅进行一步submit就可以了。
 
那么就看一下monitorAndPrintJob这个函数吧,核心代码如下:
 
while (!isComplete() || !reportedAfterCompletion) {
if (isComplete()) {
reportedAfterCompletion = true;
} else {
Thread.sleep(progMonitorPollIntervalMillis);
}
if (status.getState() == JobStatus.State.PREP) {
continue;
}
if (!reportedUberMode) {
reportedUberMode = true;
LOG.info("Job " + jobId + " running in uber mode : " + isUber());
}
String report =
(" map " + StringUtils.formatPercent(mapProgress(), 0)+
" reduce " +
StringUtils.formatPercent(reduceProgress(), 0));
if (!report.equals(lastReport)) {
LOG.info(report);
lastReport = report;
} TaskCompletionEvent[] events =
getTaskCompletionEvents(eventCounter, 10);
eventCounter += events.length;
printTaskEvents(events, filter, profiling, mapRanges, reduceRanges);
}
boolean success = isSuccessful();
if (success) {
LOG.info("Job " + jobId + " completed successfully");
} else {
LOG.info("Job " + jobId + " failed with state " + status.getState() +
" due to: " + status.getFailureInfo());
}
Counters counters = getCounters();
if (counters != null) {
LOG.info(counters.toString());
}
return success;
其实就是定时循环去报告,检查状态,其中涉及到map和reduce的总体进度(通过某种算法计算出来的百分比),如果报告与上一次有变化,就进行输出。直到任务执行完成,并将其中的所有Counter均打印出来;如果任务失败,打印出任务执行失败的原因。
 
最终,MapReduce的执行日志大概就是这个样子:
 
15/04/13 15:01:08 INFO mapreduce.Job:  map 96% reduce 28%
15/04/13 15:01:09 INFO mapreduce.Job: map 98% reduce 28%
15/04/13 15:01:10 INFO mapreduce.Job: map 98% reduce 32%
15/04/13 15:01:13 INFO mapreduce.Job: map 100% reduce 33%
15/04/13 15:01:16 INFO mapreduce.Job: map 100% reduce 37%
15/04/13 15:01:19 INFO mapreduce.Job: map 100% reduce 46%
15/04/13 15:01:22 INFO mapreduce.Job: map 100% reduce 54%
15/04/13 15:01:25 INFO mapreduce.Job: map 100% reduce 62%
15/04/13 15:01:28 INFO mapreduce.Job: map 100% reduce 68%
15/04/13 15:01:31 INFO mapreduce.Job: map 100% reduce 71%
15/04/13 15:01:34 INFO mapreduce.Job: map 100% reduce 76%
15/04/13 15:01:35 INFO mapreduce.Job: map 100% reduce 100%
15/04/13 15:01:37 INFO mapreduce.Job: Job job_1421455790417_222365 completed successfully
15/04/13 15:01:37 INFO mapreduce.Job: Counters: 46
File System Counters
FILE: Number of bytes read=70894655
FILE: Number of bytes written=158829484
FILE: Number of read operations=0
FILE: Number of large read operations=0
FILE: Number of write operations=0
HDFS: Number of bytes read=5151416348
HDFS: Number of bytes written=78309
HDFS: Number of read operations=1091
HDFS: Number of large read operations=0
HDFS: Number of write operations=2
Shuffle Errors
BAD_ID=0
CONNECTION=0
IO_ERROR=0
WRONG_LENGTH=0
WRONG_MAP=0
WRONG_REDUCE=0
 
 
如果我们需要将任务执行进度打印出来,就可以对这部分的功能就行改进并重写。
 
如果任务已经提交到集群,可以使用job对象的getTrackingURL()通过页面的形式查看到其具体详情,其中job对象还提供了一些可以操作集群任务的API,包括killTask, failTask等。
 
在任务执行完成后,就可以得到任务的所有Counter,使用Counter来对任务的各项指标进行详细统计是非常易用有效的方式,我们在任务中定义了大量的Counter来进行该操作(包括以后以后可能会评估任务的消耗,以便进行费用统计等…)。
 
如果需要启动多个任务,或以某种依赖的方式启动多个顺序MapReduce任务,可以使用JobControl来链接多个任务,JobControl的run方法,会根据任务的依赖关系来调度整个过程,并提供了一些常用的API,同样可以将任务kill/fail掉。但是如果流程的复杂性稍微比较高的情况下,建议使用一套工作流系统,例如oozie,便于管理以及应对流程上的变化。 
 
 
 
 

Hadoop MapReduce任务的启动分析的更多相关文章

  1. Hadoop MapReduce执行过程实例分析

    1.MapReduce是如何执行任务的?2.Mapper任务是怎样的一个过程?3.Reduce是如何执行任务的?4.键值对是如何编号的?5.实例,如何计算没见最高气温? 分析MapReduce执行过程 ...

  2. 使用hadoop mapreduce分析mongodb数据

    使用hadoop mapreduce分析mongodb数据 (现在很多互联网爬虫将数据存入mongdb中,所以研究了一下,写此文档) 版权声明:本文为yunshuxueyuan原创文章.如需转载请标明 ...

  3. 【Big Data - Hadoop - MapReduce】初学Hadoop之图解MapReduce与WordCount示例分析

    Hadoop的框架最核心的设计就是:HDFS和MapReduce.HDFS为海量的数据提供了存储,MapReduce则为海量的数据提供了计算. HDFS是Google File System(GFS) ...

  4. 初学Hadoop之图解MapReduce与WordCount示例分析

    Hadoop的框架最核心的设计就是:HDFS和MapReduce.HDFS为海量的数据提供了存储,MapReduce则为海量的数据提供了计算. HDFS是Google File System(GFS) ...

  5. Hadoop MapReduce编程 API入门系列之MapReduce多种输出格式分析(十九)

    不多说,直接上代码. 假如这里有一份邮箱数据文件,我们期望统计邮箱出现次数并按照邮箱的类别,将这些邮箱分别输出到不同文件路径下. 代码版本1 package zhouls.bigdata.myMapR ...

  6. hadoop MapReduce Yarn运行机制

    原 Hadoop MapReduce 框架的问题 原hadoop的MapReduce框架图 从上图中可以清楚的看出原 MapReduce 程序的流程及设计思路: 首先用户程序 (JobClient) ...

  7. 四种方案:将OpenStack私有云部署到Hadoop MapReduce环境中

    摘要:OpenStack与Hadoop被誉为继Linux之后最有可能获得巨大成功的开源项目.这二者如何结合成为更猛的新方案?业内给出两种答案:Hadoop跑在OpenStack上或OpenStack部 ...

  8. Hadoop Mapreduce 参数 (一)

    参考 hadoop权威指南 第六章,6.4节 背景 hadoop,mapreduce就如MVC,spring一样现在已经是烂大街了,虽然用过,但是说看过源码么,没有,调过参数么?调过,调到刚好能跑起来 ...

  9. [python]使用python实现Hadoop MapReduce程序:计算一组数据的均值和方差

    这是参照<机器学习实战>中第15章“大数据与MapReduce”的内容,因为作者写作时hadoop版本和现在的版本相差很大,所以在Hadoop上运行python写的MapReduce程序时 ...

随机推荐

  1. Jquery EasyUI Tree树形结构的Java实现(实体转换VO)

    前一阵做的OA项目,有一个是组织架构的树,因为是分开做的,我做的是Controller和页面,其他组做的Service和Dao,因为之前一直没有商量页面用什么框架做比较好,导致,Dao层取出来的数据都 ...

  2. python中pickle模块与base64模块的使用

    pickle模块的使用 pickle模块是python的标准模块,提供了对于python数据的序列化操作,可以将数据转换为bytes类型,其序列化速度比json模块要高. pickle.dumps() ...

  3. 浅谈js异步

    大家都知道,js是一个单线程的语言(只有一个线程来执行js函数),所以如果某一个函数执行任务耗时比较长的话,就会造成阻塞,使得后续任务一直处于等待状态. 一.阻塞示例 function f1(){ ; ...

  4. Openlayers3中实现台风风圈绘制算法

    概述: 台风的风圈的NE.NW.SW.SE四个方位的影响范围是不一致,本文介绍一种简单的风圈的绘制方法,并在OL3中展示. 实现效果: 实现代码: 1.数据格式 var Configs = { CIR ...

  5. Android中免root的hook框架Legend原理解析

    一.前言 Android中hook框架已经非常多了,最优秀的当属Xposed和Substrate了,这两个框架我在之前的文章都详细介绍过了,不了解的同学,可以转战这里:http://www.wjdia ...

  6. Linux 大文件的分割与合并

    1.分割 -- split命令 可以指定按行数分割和按字节大小分割两种模式. (1) 按行数分割 $ large_file.txt new_file_prefix 加上-d,使用数字后缀:加上--ve ...

  7. HTML中Div、span、label标签的区别

    div与span 大家在初学div+css布局时,有很多困惑,在div与span的使用过程没觉得有一定的”章法”,觉得两个区别不大,在w3c的关于div和span的定义:div作为分割文档结构自然使它 ...

  8. linux另一种安装方式

    linux中其实没有“安装”的概念:安装就是设下路径,拷贝文件,复制文件,运行下脚本这些(windows也应该如此) 法一.把bin运行路径设成环境变量 法二.ln一下,例如: 解压下载的文件: ta ...

  9. 【剑指offer】滑动窗口的最大值,C++实现

    原创博文,转载请注明出处! # 题目 # 思路 利用C++中的双端队列保存有可能是滑动窗口最大值的下标,其中队首元素保存当前窗口最大值的下标.当滑动窗口改变时,更新队列.队列更新的规则:(1)新元素依 ...

  10. Luogu 3690 Link Cut Tree

    Luogu 3690 Link Cut Tree \(LCT\) 模板题.可以参考讲解和这份码风(个人认为)良好的代码. 注意用 \(set\) 来维护实际图中两点是否有直接连边,否则无脑 \(Lin ...