项目需要实现一个原生mapreduce程序、sqoop、hive和pig脚本的代理命令行,类似于azkaban的使用方式,用户可以提交编译好的mapreduce程序(可以是一个jar包,在配置中执行入口class名)、hive命令或者脚本、sqoop命令和pig脚本。由于这些命令的执行过程中可能会生成mapreduce任务并提交到hadoop集群上执行,为了方便用户查看每一个用户提交的任务的执行状态,我们需要获得用户提交任务生成的mapreduce任务的jobId,进而可以通过hadoop提供的API查看job的状态,首先需要面临的两个问题:如何判断哪些用户提交的任务会生成mapreduce任务;如何获取用户提交任务生成的一个或者多个mapreduce任务的jobId。
当前使用的版本是:hadoop2.2.0官方版,hive 0.13.1和sqoop 1.4.5
1、mapreduce日志输出
一般情况下在命令行提交mapreduce程序的时候,会等待mapreduce程序执行直到job执行完成,在mapreduce client中默认的日志级别是INFO,以Word Count为例:
public static void main(String[] args) throws Exception {
Configuration conf = new Configuration();
String[] otherArgs = new GenericOptionsParser(conf, args).getRemainingArgs();
if (otherArgs.length != 2) {
System.err.println("Usage: wordcount <in> <out>");
System.exit(2);
}
Job job = new Job(conf, "word count");
job.setJarByClass(WordCount.class);
job.setMapperClass(TokenizerMapper.class);
job.setCombinerClass(IntSumReducer.class);
job.setReducerClass(IntSumReducer.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(IntWritable.class);
FileInputFormat.addInputPath(job, new Path(otherArgs[0]));
FileOutputFormat.setOutputPath(job, new Path(otherArgs[1]));
System.exit(job.waitForCompletion(true) ? 0 : 1);
}
首先需要创建一个Job对象( org.apache.hadoop.mapreduce.Job
),然后调用接口设置各种配置,job实现了
JobContext接口,后者继承自接口MRJobConfig,在MRJobConfig中可以看到所有的job的配置项,Job的状态有两个DEFINE和RUNNING(JobState),在job配置完成之后调用waitForCompletion可以同步得提交并等待job执行完成,函数定义如下:
1282 public boolean waitForCompletion(boolean verbose
1283 ) throws IOException, InterruptedException,
1284 ClassNotFoundException {
1285 if (state == JobState.DEFINE) {
1286 submit(); //提交任务,如果重复提交不会出错
1287 }
1288 if (verbose) {
1289 monitorAndPrintJob(); //如果参数为true则打印job执行的日志输出
1290 } else {
1291 // get the completion poll interval from the client.
1292 int completionPollIntervalMillis =
1293 Job.getCompletionPollInterval(cluster.getConf());
1294 while (!isComplete()) {
1295 try {
1296 Thread.sleep(completionPollIntervalMillis);
1297 } catch (InterruptedException ie) {
1298 }
1299 }