HADOOP word count example (ver.2 for hadoop ver.2.x)

이제 하둡을 이용한 간단한 예제문을 실행시켜 볼 차례입니다.

먼저 모든 노드를 활성화 시켜줍니다.

$ start-all.sh

$ gedit test.txt &

gedit을 열어서 test.txt 파일을 만들어준 후.... 여기선 단어를 세어주는 프로그램 테스트이므로 문장을 작성해 봅니다.

$ hdfs dfs -put test.txt /input

HDFS(Hadoop Distributed File System)에 input 폴더를 만들고 그안에 위에서 작성한 test파일을 넣어줍니다.

이제 Map과 Reduce job을 위한 Java코드를 작성해 봅니다.

<JAVA Source Code>

import java.io.IOException;
import java.util.StringTokenizer;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;

public class WordCount {

  public static class TokenizerMapper
       extends Mapper<Object, Text, Text, IntWritable>{

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

    public void map(Object key, Text value, Context context
                    ) throws IOException, InterruptedException {
      StringTokenizer itr = new StringTokenizer(value.toString());
      while (itr.hasMoreTokens()) {
        word.set(itr.nextToken());
        context.write(word, one);
      }
    }
  }

  public static class IntSumReducer
       extends Reducer<Text,IntWritable,Text,IntWritable> {
    private IntWritable result = new IntWritable();

    public void reduce(Text key, Iterable<IntWritable> values,
                       Context context
                       ) throws IOException, InterruptedException {
      int sum = 0;
      for (IntWritable val : values) {
        sum += val.get();
      }
      result.set(sum);
      context.write(key, result);
    }
  }

  public static void main(String[] args) throws Exception {
    Configuration conf = new Configuration();
    Job job = Job.getInstance(conf, "word count");
    job.setJarByClass(WordCount.class);
    job.setMapperClass(TokenizerMapper.class);
    job.setCombinerClass(IntSumReducer.class);
    job.setReducerClass(IntSumReducer.class);
    job.setOutputKeyClass(Text.class);
    job.setOutputValueClass(IntWritable.class);
    FileInputFormat.addInputPath(job, new Path(args[0]));
    FileOutputFormat.setOutputPath(job, new Path(args[1]));
    System.exit(job.waitForCompletion(true) ? 0 : 1);
  }
}

위의 코드를 테스트 해보고 싶으시다면... 복사해서 붙여넣어주세요.

$ gedit WordCount.java &  // 후에 복사하신 내용을 붙여넣고 저장.

이제 컴파일해 줍니다.

$ hadoop com.sun.tools.javac.Main WordCount.java

jar 파일을 생성해야 겠죠?

$ jar -cf wc.jar WordCount*.class

이제 하둡을 이용해서 맵 리듀스를 해봅니다.

$ hadoop jar wc.jar WordCount /input /output         //여기서 한가지 이미 output 폴더가 존재한다면 실행이 되지 않네요.

맵과 리듀스가 완료되었을 것입니다. 그럼 결과를 확인....

$ hdfs dfs -cat /output/part-r-00000

결과를 읽어옵니다. 오늘은 간단히 여기까지만 하고 이후에 스크린샷을 아래에 추가해서 보다 알아보기 쉽게 만들예정입니다.

이후의 내용은 위의 예제를 조금 바꾸어서 두개의 단어가 Pair key 값이 되도록 하여 그 페어키값을 카운트해 볼 생각입니다.