2012-04-02 7 views
1

Ich habe diesen Code verwendet, um den Wortzahl-Hadoop-Job auszuführen. WordCountDriver wird ausgeführt, wenn ich es mit dem Hadoop-Eclipse-Plugin aus Eclipse heraus starte. WordCountDriver wird auch über die Befehlszeile ausgeführt, wenn ich die Mapper- und Reducer-Klassen als jar verpacke und im Klassenpfad ablege.Aufrufen eines Hadoop-Jobs aus Java-Code ohne Jar

Es schlägt jedoch fehl, wenn ich versuche, es von der Befehlszeile auszuführen, ohne die Mapper- und Reduziererklasse als ein Jar zu dem Klassenpfad hinzuzufügen, obwohl ich beide Klassen dem Klassenpfad hinzufügte. Ich wollte wissen, gibt es einige Einschränkungen in Hadoop von der Annahme von Mapper & Reducer-Klassen als normale Klassendateien. Ist das Erstellen eines Glases immer obligatorisch?

public class WordCountDriver extends Configured implements Tool {

public static final String HADOOP_ROOT_DIR = "hdfs://universe:54310/app/hadoop/tmp"; 


static class WordCountMapper extends Mapper<LongWritable, Text, Text, IntWritable> { 

    private Text word = new Text(); 
    private final IntWritable one = new IntWritable(1); 

    public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException { 

     String line = value.toString(); 
     StringTokenizer itr = new StringTokenizer(line.toLowerCase()); 
     while (itr.hasMoreTokens()) { 
      word.set(itr.nextToken()); 
      context.write(word, one); 
     } 
    } 
}; 

static class WordCountReducer extends Reducer<Text, IntWritable, Text, IntWritable> { 

    public void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException { 

     int sum = 0; 

     for (IntWritable value : values) { 
      sum += value.get(); // process value 
     }  
     context.write(key, new IntWritable(sum)); 
    } 
}; 


/** 
* 
*/ 
public int run(String[] args) throws Exception { 

    Configuration conf = getConf(); 

    conf.set("mapred.job.tracker", "universe:54311"); 

    Job job = new Job(conf, "Word Count"); 

    // specify output types 
    job.setOutputKeyClass(Text.class); 
    job.setOutputValueClass(IntWritable.class); 

    // specify input and output dirs 
    FileInputFormat.addInputPath(job, new Path(HADOOP_ROOT_DIR + "/input")); 
    FileOutputFormat.setOutputPath(job, new Path(HADOOP_ROOT_DIR + "/output")); 

    // specify a mapper 
    job.setMapperClass(WordCountDriver.WordCountMapper.class); 

    // specify a reducer 
    job.setReducerClass(WordCountDriver.WordCountReducer.class); 
    job.setCombinerClass(WordCountDriver.WordCountReducer.class); 

    job.setJarByClass(WordCountDriver.WordCountMapper.class); 

    return job.waitForCompletion(true) ? 0 : 1; 
} 

/** 
* 
* @param args 
* @throws Exception 
*/ 
public static void main(String[] args) throws Exception { 
    int res = ToolRunner.run(new Configuration(), new WordCountDriver(), args); 
    System.exit(res); 
} 

}

Antwort

1

Es ist nicht ganz klar, die Sie sich beziehen, aber am Ende classpath, wenn Sie auf einem Remote Hadoop Cluster laufen lassen, müssen Sie alle Klassen in einer JAR-Datei schaffen, die wird während der hadoop jar Ausführung an Hadoop gesendet. Der Klassenpfad Ihres lokalen Programms ist irrelevant.

Wahrscheinlich arbeitet es lokal, da Sie tatsächlich eine Hadoop-Instanz innerhalb des lokalen Prozesses dort ausführen. In diesem Fall ist es möglich, die Klassen im Klassenpfad Ihres lokalen Programms zu finden.

+0

Mein Fahrer Klasse ist lokal und hadoop ist Setup als 1-Knoten-Cluster – cosmos

1

Durch das Hinzufügen von Klassen zum Hadoop-Klassenpfad werden diese Client-Seite (d. H. Für Ihren Treiber) verfügbar gemacht.

Ihr Mapper und Reducer müssen Cluster-weit verfügbar sein, und um dies auf hadoop zu erleichtern, bündeln Sie sie in einem Jar und liefern entweder mit der Klasse Job.setJarByClass (..) oder fügen sie zu der Klasse hinzu Job classpath die -libjars Option mit dem GenericOptionsParser mit: