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