Я пишу программу, которая получает исходный код картографов/редукторов, динамически компилирует мапперы/редукторы и создает из них JAR-файл. Затем он должен запустить этот JAR-файл в кластере Hadoop.
В последней части я динамически настраиваю все необходимые параметры через свой код. Однако проблема, с которой я столкнулся сейчас, заключается в том, что коду требуются скомпилированные классы преобразователя и редуктора во время компиляции. Но на момент компиляции у меня нет этих классов и они позже будут получены во время выполнения (например, через сообщение, полученное от удаленного узла). Буду признателен за любую идею/предложение о том, как решить эту проблему?
Ниже вы можете найти код для моей последней части с проблемой в job.setMapperClass(Mapper_Class.class) и job.setReducerClass(Reducer_Class.class), требующих, чтобы файлы классов (Mapper_Class.class и Reducer_Class.class) присутствовали в время составления:
private boolean run_Hadoop_Job(String className){
try{
System.out.println("Starting to run the code on Hadoop...");
String[] argsTemp = { "project_test/input", "project_test/output" };
// create a configuration
Configuration conf = new Configuration();
conf.set("fs.default.name", "hdfs://localhost:54310");
conf.set("mapred.job.tracker", "localhost:54311");
conf.set("mapred.jar", jar_Output_Folder+ java.io.File.separator
+ className+".jar");
conf.set("mapreduce.map.class", "Mapper_Reducer_Classes$Mapper_Class.class");
conf.set("mapreduce.reduce.class", "Mapper_Reducer_Classes$Reducer_Class.class");
// create a new job based on the configuration
Job job = new Job(conf, "Hadoop Example for dynamically and programmatically compiling-running a job");
job.setJarByClass(Platform.class);
//job.setMapperClass(Mapper_Class.class);
//job.setReducerClass(Reducer_Class.class);
// key/value of your reducer output
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(IntWritable.class);
FileInputFormat.addInputPath(job, new Path(argsTemp[0]));
// this deletes possible output paths to prevent job failures
FileSystem fs = FileSystem.get(conf);
Path out = new Path(argsTemp[1]);
fs.delete(out, true);
// finally set the empty out path
FileOutputFormat.setOutputPath(job, new Path(argsTemp[1]));
//job.submit();
System.exit(job.waitForCompletion(true) ? 0 : 1);
System.out.println("Job Finished!");
} catch (Exception e) { return false; }
return true;
}
Пересмотрено: поэтому я пересмотрел код, чтобы указать преобразователь и редукторы с помощью conf.set("mapreduce.map.class, "my mapper.class"). Теперь код компилируется правильно, но при выполнении выдает следующую ошибку:
24 декабря 2012 г. 6:49:43 org.apache.hadoop.mapred.JobClient monitorAndPrintJob INFO: Идентификатор задачи: попытка_201212240511_0006_m_000001_2, Статус: FAILED java.lang.RuntimeException: java.lang.ClassNotFoundException: Mapper_Reducer_Classesclass$Mapper_Class.Class. apache.hadoop.conf.Configuration.getClass(Configuration.java:809) в org.apache.hadoop.mapreduce.JobContext.getMapperClass(JobContext.java:157) в org.apache.hadoop.mapred.MapTask.runNewMapper(MapTask. java:569) в org.apache.hadoop.mapred.MapTask.run(MapTask.java:305) в org.apache.hadoop.mapred.Child.main(Child.java:170)