0

人気のある Hadoop の教科書の 1 つに記載されている簡単な例に従っています。コードは次のとおりです:- [私の問題の説明はプログラムの後に続きます]

package src.main.myjob;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Iterator;
import java.util.Set;

import javax.lang.model.SourceVersion;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.conf.Configured;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapred.FileInputFormat;
import org.apache.hadoop.mapred.FileOutputFormat;
import org.apache.hadoop.mapred.JobClient;
import org.apache.hadoop.mapred.JobConf;
import org.apache.hadoop.mapred.KeyValueTextInputFormat;
import org.apache.hadoop.mapred.MapReduceBase;
import org.apache.hadoop.mapred.Mapper;
import org.apache.hadoop.mapred.OutputCollector;
import org.apache.hadoop.mapred.Reducer;
import org.apache.hadoop.mapred.Reporter;
import org.apache.hadoop.mapred.TextOutputFormat;
import org.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner;

public class MyJob extends Configured implements Tool
{
    public static class MapClass extends MapReduceBase implements Mapper<Text, Text, Text, Text>
    {

        @Override
        public void map(Text key, Text value, OutputCollector<Text, Text> output, Reporter reporter) throws IOException 
        {
        output.collect(value, key); 
        }
    }

    public static class Reduce extends MapReduceBase implements Reducer<Text, Text, Text, Text>
    {
            public void reduce(Text key, Iterator<Text> values, OutputCollector<Text, Text> output, Reporter reporter) throws IOException
            {
                String csv = "";
                while(values.hasNext())
                {
        csv += values.next().toString();
                        csv += ",";
                }
                output.collect(key, new Text(csv));
            }
    }


    @Override
    public int run(String[] args) throws Exception
    {
        Configuration conf = new Configuration();
        JobConf job = new JobConf(conf, MyJob.class);

        Path in = new Path(args[0]);
        Path out = new Path(args[1]);

        FileInputFormat.setInputPaths(job, in);
        FileOutputFormat.setOutputPath(job, out);

        job.setJobName("MyJob");
        job.setMapperClass(MapClass.class);
        job.setReducerClass(Reduce.class);

        job.setInputFormat(KeyValueTextInputFormat.class);
        job.setOutputFormat(TextOutputFormat.class);

        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(Text.class);

        job.set("key.value.seperator.in.input.line", ",");

        JobClient.runJob(job);

        return 0;
    }

    public static void main(String[] args) throws Exception
    {
        int res = ToolRunner.run(new Configuration(), new MyJob(), args);

        System.exit(res);
    }


}

読者の便宜のために、このプログラムはすべて、引用特許 ID と引用特許 ID の行を含むファイル [巨大なファイル] を処理し、それを反転します。したがって、基本的に、出力ファイルにはすべての特許 ID がリストされ、それぞれの後に引用特許 ID のカンマ区切りのリストが続きます。

実行しようとすると、Map タスクは非常にうまく実行されますが、reduce タスクは 66% で停止します。ログを調べたり(非常に不可解でほとんど役に立たない)、レデューサーの数を増やしたりするなど、さまざまなことを試しました。しかし、私は問題を理解することにほとんど成功していません。コードは私には簡単に見えます。ここでこの問題をデバッグする方法を理解するのに役立つ情報を提供していただければ幸いです。このプログラムには明らかな問題はありません。

4

2 に答える 2

0

まず、StringBuilder文字列を連結しようとしている場合は、reducer で追加することを検討してください。データのサイズが巨大な場合、そのループのパフォーマンスは向上します。

StringBuilder sb = new StringBuilder();
sb.append(values.next().toString());

次に、処理するデータのセットが非常に大きい場合は、リデューサーに十分なメモリがあることを確認してください。

于 2013-09-29T14:51:26.480 に答える
0

この質問の補足として、私はついに MapReduce プログラムを完成させることに成功しました。上記の投稿で JthRocker が提案しているように、hadoop のメモリ割り当てを mapred-site.xml 内で 6 ギガに増やし、文字列ビルダーも使用する必要がありました。完了しましたが、出力ファイルを読み取ることができません。ubuntu は、サイズが 258MB であることを示しており、これは私の入力ファイルよりわずかに小さいです。私のコード自体の欠陥ではないかと思っていましたか? または、データがエディターに適した形式で適切に書き込まれていないため、解釈の問題が発生している場合は? これに関するすべての入力は高く評価されています。

于 2013-10-01T15:43:43.693 に答える