MapReduce作业提交过程

hadoop jar  [mainClass] args...

上面这一行,是官方文档[1]给出的用于提交MapReduce作业的命令行。我们就从这一命令开始说起,研究一下当我们在SecureCRT或者XShell等终端将它提交后,系统依次发生了什么。

为了方便说明,我们结合Hadoop(版本0.19.1)自带的WordCount样例进行解析,WordCount的功能是计算出一个或多个文本中每个单词出现的次数。该样例存在于hadoop-0.19.1-examples.jar包中,源代码可以在src文件夹下获得,详细路径是\src\examples\org\apache\hadoop\examples\WordCount.java)。

磨刀不误砍柴工,我们先把必要的准备工作做好:
  • 准备一个待统计的样例文本(我找了马丁·路德·金的经典演讲“I hava a dream”,你们随意,只有是英文的就好),将其从本地put到HDFS中,记住包含文件名的完整路径(记为$input)。
  • 建好输出文件路径(不需要文件名,记为$output)
  • 将WordCount.java的代码单独copy出来,在eclipse中单独打一个jar包,命名为wordcount.jar,记住该jar包的路径(记为$usrjar)。
现在,了解一下这个命令行的结构。这里,选项是我们打包好的jar包的详细路径,是必选项;[mainClass]是包中含main()方法的类,也是任务执行的入口,不过看它这样子,是个可选项,猜测一下应该是当jar包中只有一个类的时候可以省略类名(后面可以验证);args可以详细给出若干个参数,并在main()方法中予以解析。也就是说,提交MapReduce作业的命令,跟我们运行普通java类的命令,基本原理是一致的,就是要寻找到main()方法的类,并把需要传入的参数放到命令行中;传入的参数同样会被传递到我们所熟悉的args[]数组中。一般来说,args所列的参数,应该至少包含输入数据的路径,以及输出数据要存放的地址,因为没有它们,你将不知道数据从何而来,欲往何处。当然,这都是视该任务要解决的具体问题,以及main()方法中如何处理输入参数而定的。

我们把输入数据、jar包都放置到正确地方后,就可以通过以下方法提交WordCount任务:
hadoop jar $usrjar org.apache.hadoop.examples.WordCount $input $output

以上请自觉将$usrjar、$input、$output改为相应字符串(或者也可以建立一个shell文件,定义好$usrjar等变量,更方便直观看出命令行的本质)。

按下enter键,程序开始执行并进入main方法。此时args数组的值如下:
args[0] = $input所代表的字符串
args[1] = $output所代表的字符串

下面进入main方法。第一行是:
int res = ToolRunner.run(new Configuration(), new WordCount(), args);

我们先不分析ToolRunner的作用(但这是一个非常好的东西,有机会单独研究下)。由于在run方法的参数中使用new WordCount()创造了一个实例,并且args也完整传入到run方法中,直觉告诉我们,args会被传入到WordCount的某些方法,从而开始真正的个性化任务,而且执行下一步任务的,应该就是WordCount的run方法,因为run方法的完整定义是:
public int run(String[] args) throws Exception
你看到熟悉的args了吗?

源代码告诉我们,直觉是对的。

阶段总结下以上内容:
  • 执行hadoop jar命令;
  • $input和$output传入args数组;
  • args数组传入ToolRunner的run方法;
  • args数组继续传入WordCount的run方法。
现在我们直接将目光转向WordCount的run方法。WordCount的run方法代码较多,大部分是准备工作,核心代码在最后:
FileInputFormat.setInputPaths(conf, (String) other_args.get(0));
FileOutputFormat.setOutputPath(conf, new Path((String) other_args.get(1)));
JobClient.runJob(conf);
第1行读取args[0],也就是$input,设置数据输入路径。
第2行读取args[1],即$output,设置数据输出路径。
第3行正式启动一个任务(job)。

runJob方法启动后,有很多步骤对我们而言就是黑盒的了,如数据分发、任务调度等。黑盒子的流程我们可以暂时不关心,hadoop是个好管家,黑盒中的代码一般情况下也不需要修改。我们只需知道,当hadoop集群的两大核心角色——JobTracker(负责任务调度)和TaskTracker(负责任务执行)开始有序工作后,具体的执行任务便落到了map方法和reduce方法上。

接下来的故事就很落入俗套了:MapReduce计算模型的文章,可以搜索到非常多。

感受一下吧!

[1] http://hadoop.apache.org/docs/current/hadoop-project-dist/hadoop-common/CommandsManual.html#jar


你可能感兴趣的:(Hadoop技术)