2

マッパー/リデューサーのソース コードを受け取り、マッパー/リデューサーを動的にコンパイルして、それらから JAR ファイルを作成するプログラムを作成しています。次に、この JAR ファイルを Hadoop クラスターで実行する必要があります。

最後の部分では、必要なすべてのパラメーターをコードを通じて動的にセットアップします。しかし、私が今直面している問題は、コードがコンパイル時にコンパイルされたマッパーとリデューサー クラスを必要とすることです。しかし、コンパイル時にはこれらのクラスがなく、後で実行時に (たとえば、リモート ノードから受信したメッセージを介して) 受信されます。この問題を解決する方法についてのアイデア/提案をいただければ幸いです。

以下は、クラス(Mapper_Class.classおよびReducer_Class.class)ファイルが存在する必要があるjob.setMapperClass(Mapper_Class.class)およびjob.setReducerClass(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") を使用してマッパーとリデューサーを指定するようにコードを改訂しました。コードは正しくコンパイルされるようになりましたが、実行すると次のエラーがスローされます。

ec 24, 2012 6:49:43 AM org.apache.hadoop.mapred.JobClient monitorAndPrintJob 情報: タスク ID: 試行_201212240511_0006_m_000001_2、ステータス: 失敗しました java.lang.RuntimeException: java.lang.ClassNotFoundException: org. 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) で

4

3 に答える 3

2

コンパイル時にそれらがない場合は、次のように構成で名前を直接設定します。

conf.set("mapreduce.map.class", "org.what.ever.ClassName");
conf.set("mapreduce.reduce.class", "org.what.ever.ClassName");
于 2012-12-23T13:41:24.620 に答える
1

問題は、TaskTracker がローカル jRE のクラスを認識できないことです。

私はこの方法でそれを理解しました(Mavenプロジェクト);

まず、このプラグインを pom.xml に追加します。これにより、すべての依存関係 jar を含むアプリケーション jar ファイルがビルドされます。

 <build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-shade-plugin</artifactId>
            <executions>
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>shade</goal>
                    </goals>
                </execution>
            </executions>
            <configuration>
                <filters>
                    <filter>
                        <artifact>*:*</artifact>
                        <excludes>
                            <exclude>META-INF/*.SF</exclude>
                            <exclude>META-INF/*.DSA</exclude>
                            <exclude>META-INF/*.RSA</exclude>
                        </excludes>
                    </filter>
                </filters>
                <finalName>sample</finalName>
                <!-- 
                <finalName>uber-${artifactId}-${version}</finalName>
                -->
            </configuration>
        </plugin>
    </plugins>
  </build>

Java ソース コードにこれらの行を追加すると、pom.xml の上記のタグによって target/sample.jar にビルドされた sample.jar が含まれます。

      Configuration config = new Configuration();
      config.set("fs.default.name", "hdfs://ip:port");
      config.set("mapred.job.tracker", "hdfs://ip:port");

      JobConf job = new JobConf(config);
      job.setJar("target/sample.jar");

このように、タスクトラッカーは作成したクラスを参照でき、ClassNotFoundException は発生しません。

于 2013-08-26T02:37:23.470 に答える
0

動的に作成されるクラスの Class オブジェクトへの参照のみが必要です。Class.for name("foo.Mapper")の代わりに使用foo.Mapper.class

于 2012-12-23T14:24:01.643 に答える