MapReduce框架学习(3)——Job的创建及配置

参考: JeffreyZhou的博客园
《Hadoop权威指南》第四版

0

一个MR作业,包括三点:

  • 输入数据
  • MR程序
  • Job配置信息

前面两篇学习了数据格式和MR过程(map函数和reduce函数),那么今天再讲一下配置信息,是怎么把 数据 和 程序结合起来的。

3.1 代码

Job对象指定作业执行规范,我们可以用它来控制整个作业的运行。打算对照代码来讲解,这样可能要有逻辑一点,不至于讲到最后都不知道自己的线索在哪。先贴上WordCount中的Job任务代码:

public static void main(String[] args) throws Exception {
	Configuration conf = new Configuration();   // 配置文件
	// System.out.println("url:" + conf.get("fs.default.name"));  // deprecated
	// System.out.println("url:" + conf.get("fs.defaultFS"));
	
// 获取一个作业
	// Job job = new Job(conf, "word count");  // deprecated
	Job job = Job.getInstance(conf,"wordcount");  // 用job的静态方法
// 设置job所用的那些类(class)文件在哪个jar包
	job.setJarByClass(WordCount.class);
// 设置所用的map reduce类
	job.setMapperClass(TokenizerMapper.class);
	job.setCombinerClass(IntSumReducer.class);  // 对每个节点的map输出进行combine
	job.setReducerClass(IntSumReducer.class);  // 对所有节点的输出进行reduce

// 设置数据输出类型
	job.setOutputKeyClass(Text.class);
	job.setOutputValueClass(IntWritable.class);
// 指定要处理的输入、输出路径,
	//此处输入/出为固定文件目录
	FileInputFormat.addInputPath(job, "input");
	FileOutputFormat.setOutputPath(job, "output");
	//此处为参数
	// FileInputFormat.addInputPath(job, new Path(otherArgs[0]));
	// FileOutputFormat.setOutputPath(job, new Path(otherArgs[1]));
	
// 将job提交给集群运行
	System.exit(job.waitForCompletion(true) ? 0 : 1);

那么,现在对照上面的代码来分析作业提交到执行的整个过程吧。

3.2 创建Job

任务创建比较容易,其实就是new一个实例,先创建一个配置文件的对象,然后将配置文件,以及作业名称作为参数,构造一个Job对象就行了

Configuration conf = new Configuration();   // 配置文件
Job job = Job.getInstance(conf,"wordcount");  // 用job的静态方法

3.3 打包作业

我们在Hadoop集群上运行这个作业时,要把代码打包成一个JAR文件(Hadoop在集群上发布这个文件),关于打包JAR,大概意思就是把程序运行所需要的包啊类啊啥的,全部形成一个压缩包,但这个工作不用我们自己去一个个找,只要在Job对象的setJarByClass()方法中传递一个类即可,Hadoop会利用这个类来查找包含它的JAR文件,进而找到相关的JAR文件。

// 将job所用的那些类(class)文件,打成jar包
job.setJarByClass(WordCount.class);

3.4 设置各个环节的函数

这个很好理解,上一篇博文分析了MR过程中的各个环节,这些环节都是可以自定义的,就是在Job里面设置,将自定义的函数和具体作业联系起来。

job.setMapperClass(TokenizerMapper.class);
job.setCombinerClass(IntSumReducer.class);  // 对每个节点的map输出进行combine
job.setPartitionerClass(MyPartitioner.class); // 对每个节点的map输出进行partition
job.setReducerClass(IntSumReducer.class);  // 对所有节点的输出进行reduce

3.5 设置输入输出数据类型

job.setInputFormatClass(MyInputFormat.class);
job.setOutputFormatClass(TextOutputFormat.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(IntWritable.class);

3.6 设置输入输出文件目录

在设置输入输出文件目录时,可以选择使用绝对目录,就是直接在语句中写入目录;也可以使用参数输入,即在运行程序时,再在控制台输入目录。

// 指定要处理的输入、输出路径,
	//此处输入/出为固定文件目录
	FileInputFormat.addInputPath(job, "input");
	FileOutputFormat.setOutputPath(job, "output");
	//此处为参数
	// FileInputFormat.addInputPath(job, new Path(otherArgs[0]));
	// FileOutputFormat.setOutputPath(job, new Path(otherArgs[1]));

3.7 提交并运行作业

单个任务的执行

可以直接使用语句:

job.waitForCompletion(true)

waitForCompletion()方法提交作业并等待执行完成,该方法唯一的参数是一个标识,指示是否已生成详细输出,当标识为true(成功)时,作业会把其进度写到控制台。
–《Hadoop权威指南》第四版,28页

多个任务执行

多个任务的话,就有多种组织形式,例如串行、并行、无关、组合。如下图:

在这里插入图片描述
图中,Job2和Job3将会等Job1执行完了再执行,且可以同时开始,而Job4必须等Job2和Job3同时结束后才结束。

这个组合,就可以采用这样的代码来实现:

Configuration conf = new Configuration();
Job job1 = new Job(conf, "job1");   //.. config Job1
Job job2 = new Job(conf, "job2");   //.. config Job2
Job job3 = new Job(conf, "job3");	//.. config Job3
Job job4 = new Job(conf, "job4");	//.. config Job4
 
//添加依赖关系
job2.addDependingJob(job1);
job3.addDependingJob(job1);
job4.addDependingJob(job2);
job4.addDependingJob(job3);
 
JobControl jc = new JobControl("jbo name");
jc.addJob(job1);
jc.addJob(job2);
jc.addJob(job3);
jc.addJob(job4);

jc.run();

3.x 后记

这里讲的其实偏向于作业的编程方面,但是在程序中把这些都设置好了,提交给集群后,又是怎样的运行机制呢?这个就是关于application mastermap task等方面的分析了。

猜你喜欢

转载自blog.csdn.net/qq_41059320/article/details/83387022