'wordcount'에 해당되는 글 1건

  1. 2013.04.06 [Hadoop] WordCount
반응형

Hadoop의 HelloWorld 프로그램 격인 WordCount 를 살펴보자.

 

WordCount 프로그램은 Hadoop File System 상에 있는 Text 파일을 라인 단위로 읽어서 하나의 레코드로 Map 메소드에 전달하고 해당 라인의 단어를 쪼개서 각 단어를 Key 로 그리고 Key에 대한 Value를 1로 출력하게 한다. 다시 말해서 입력 <Key=라인번호, Value=라인 Text> 가 맵 프로그램을 통해서 출력<Key=Word, Value=1> 이 되는 것이다.

 

이 출력값은 리듀서에 <Key=Word, Value=[1,1,1,....]> 이 되며 Value는 같은 Key (다시 말해 같은 Word)에 대한 1 값들의 리스트이다. 이 값은 Map 프로그램 출력 Key 값에 대해서 Value의 리스트를 전달하는 것이다.

 

리듀서는 이 <Key=Word, Value=[1,1,1,...]> 에 대해서 Value list를 iteration 하면서 값을 하나씩 증가 시키면 된다.

 

다음은 WordCount 예제이다.

 

public class WordCount {

 public static class MyMapper extends Mapper<LongWritable, Text, Text, LongWritable> {
    private final static LongWritable one = new LongWritable(1);
    private Text word = new Text();

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

         // map 프로그램은 입력으로 LongWritable  key와 Text value를 받는다. 이는 main 함수에서

         // setInputFormatClass의 TextInputFormat 클래스로 지정하였기 때문이며 TextInputFormat 클래스

         // 는 파일에서 라인단위로 읽어서 라인 번호를 Key로, 라인 텍스트를 Value로 Map 입력에 넣어준다.
        String line = value.toString();
        StringTokenizer tokenizer = new StringTokenizer(line, "\t\r\n\f |,.()<>");
        while (tokenizer.hasMoreTokens()) {
            word.set(tokenizer.nextToken().toLowerCase());
            context.write(word, one);
        }

        // Text를 StringTokenizer의 입력으로 이용하기 위해서 변환하고 tokenizer로 분리된 각 단어를 Key로

        // 이 Key에 대한 Value를 LongWritable one으로 설정해서 Map에서 출력한다.
    }
 }

 public static class MyReducer extends Reducer<Text, LongWritable, Text, LongWritable> {
    private LongWritable sumWritable = new LongWritable();

    public void reduce(Text key, Iterable<LongWritable> values, Context context)

       // Map 프로그램에서 출력된 Key, Value는 Hadoop Framework 내부에서 Key에 대한 값들이

       // 셔플링과 소팅이 되어 리듀서의 Key, Value List 값으로 들어간다.
      throws IOException, InterruptedException {
        long sum = 0;
        for (LongWritable val : values) {
            sum += val.get();
        }

        // 이 리스트에서 값을 추출하여 Sum 하면 단어 빈도가 되며
        sumWritable.set(sum);
        context.write(key, sumWritable);
         // 이 값을 리듀서의 출력으로 한다.

    }
 } 


 public static void main(String[] args) throws Exception {
    Configuration conf = new Configuration();
    Job job = new Job(conf, "WordCount");

    job.setJarByClass(WordCount.class);
    job.setMapperClass(MyMapper.class);
    job.setReducerClass(MyReducer.class);

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

 
    job.setInputFormatClass(TextInputFormat.class);

    //Map 프로그램에 들어갈 입력 포멧으로 TextInputFormat은 라인번호=Key, 라인 텍스트=Value가 된다.
    job.setOutputFormatClass(TextOutputFormat.class);

    FileInputFormat.addInputPath(job, new Path(args[0]));
    FileOutputFormat.setOutputPath(job, new Path(args[1]));

    job.waitForCompletion(true);
 }

}

 

CLASSPATH를 설정해 줘야 한는데 CLASSPATH에 잡아줘야 하는 jar 파일은 hadoop classpath 하게 되면 나온다. 이걸 쫙 CLASSPATH에 잡아준다.

컴파일은 javac WordCount.java로 하면 되며 manifest.txt 파일을 만들어서 Main-Class:WordCount 로 설정한다. 그리고 jar cmvf manifest.txt wordcount.jar ./*.class 로 wordcount.jar 파일을 만든다.

실행은 다음과 같이 한다

 

hadoop jar ./wordcount.jar [Hadoop 파일시스템상 입력파일] [Hadoop 파일시스템상출력파일]

 

 

 

 

 

반응형
Posted by alias
,