1在本地作业运行器上运行作业
通过使用前面介绍的Tool接口,可以轻松写一个MapReducer作业的驱动程序,用它来计算按照年度查找最高气温,参见范例的MaxTemperatureDriver。
范例,查找最高气温
public class MaxTemperatureDriver extends Configured implements Tool{
@Override
public int run(String[] args) throws Exception{
if(args.length!=2){
System.err.printf("Usage:%s[generic options]<input><output>\n",getClass().getSimpleName());
ToolRunner·printGenericCommandUsage(System.err);
return·1;
}
Job job=new Job(getConf(),"Maxtemperature");
job.setJarByClass(getClass());
FileInputFormat.addInputPath(job,newPath(args[0]));
FileOutputFormat.setOutputPath(job,newPath(args[1]));
job.setMapperCIass(MaxTemperatureMapper.class);
job.setCombinerC1ass(MaxTemperatureReducer·class);
job.setReducerClass(MaxTemperatureReducer·class);
job.setOutputKeyClass(Text.class);
job.setOutputVaIueClass(IntWritabIe.class);
return job.waitForCompIetion(true)?0:1;
}
public static void main(String[]args)throws Exception{
int exitCode=ToolRunner.run(new MaxTemperatureDriver(),args);
System.exit(exitCode);
}
}
MaxTemperatureDriver实现了Tool接口,所以,我们能够设置GenericOptionsParser支持的选项。run()方法根据工具的配置创建一个Job对象来启动一个作业。在所有可能的作业配置参数中,可以设置输人和输出文件路径,mapper、reducer和combiner以及输出类型(输人类型由输人格式决定,默认为TextInputFormat,包括Longwritable键和Text值)。为作业设置一个名称(Max temperature)也是很好的做法,这样可以在执行过程中或作业完成后方便地从作业列表中查找作业。默认情况下,作业名称是JAR文件名,通常情况下没有特殊的描述。现在我们可以在一些本地文件上运行这个应用。Hadoop有一个本地作业运行器(job runner),它是在MapReduce执行引擎运行单个JVM上的MapReduce作业的简化版本。它是为测试而设计的,在IDE中使用起来非常方便,因为我们可以在调试器中单步运行mapper和reducer代码。
如果mapreduce.framework.name被设置为local则使用本地作业运行器,这也是默认情况。
可以在命令行方式下输人如下命令来运行驱动程序:
mvn compile
export HADOOP_CLASSPATH=target/classes/
hadoop v2.MaxTemperatureDriver -conf conf/hadoop-local.xml input/ncdc/micro output
类似地,可以使用GenencOptionsParser提供的-fs和-jt选项:
hadoop v2.MaxTemperatureDriver -fs file:/// -jt local input/ncdc/micro output
这条指令使用本地input/ncdc/micro目录作为输入来执行MaxTenperatureDriver,产生的输出存放在本地output目录中。注意:虽然我们设置了-fs,可以使用本地文件系统(file:///),但本地作业运行器实际上可以在包括HDFS在内的任何文件系统上正常工作(如果HDFS里有一些文件,可以马上进行尝试)。
可以如下检查本地文件系统上的输出:
cat output/part-r-00000
1949111
195022
2.测试驱动程序
除了灵活的配置选项可以使应用程序实现Tool,还可以插人任意Configuration来增加可测试性。可以利用这点来编写测试程序,它将利用本地作业运行器在已知的输人数据上运行作业,借此来检查输出是否满足预期。要实现这个目标,有两种方法。第一种方法是使用本地作业运行器,在本地文件系统的测试文件上运行作业。下面范例的代码给出了一种思路。范例,这个MaxTemperatureDriver测试使用了一个正在运行的本地作业运行器。
@Test
public void test() throws Exception{
Configuration conf=new Configuration();
conf.set("fs.defaultFS","file:///");
conf.set("mapreduce.framework.name","local");
conf.setlnt("mapreduce.task.io.sort.mb",1);
Path input=new Path("input/ncdc/micro");
Path output=new Path("output");
FileSystem fs=FileSystem.getLocal(conf);
fs.delete(output,true);//delete01doutput
MaxTemperatureDriver driver=new MaxTemperatureDriver();
driver.setConf(conf);
int exitCode=driver.run(newString[]{input.toString(),output.toString()});
assertThat(exitCode,is(0));
checkOutput(conf,output);
}
测试代码明确设置了fs.defaultFS和mapreduce.framework.name所以,它使用的是本地文件系统和本地作业运行器。随后,通过其Tool接口在少数已知数据上运行MaxTemperatureDriver。最后,check0utput()方法调用以逐行对比实际输出与预期输出。
测试驱动程序的第二种方法是使用一个mini集群来运行它。Hadoop有一组测试类,名为MiniDFSCIuster、MiniMRCIuster和MiniYARNCIuster,它以程序方式创建正在运行的集群。不同于本地作业运行器,它们允许在整个HDFS、MapReduce和YARN机器上运行测试。注意,mini集群上的节点管理器启动不同的JVM来运行任务,这会使调试更困难。
也可以从命令行运行一个mini集群,如下所示:
hadoop jar $HADOOP_HOME/share/hadoop/mapreduce/hadoop-mapreduce-*-tests.jar minicluster