MapReduce 프로그램은 3부분으로 구성된다.
- Driver
- Mapper
- Reducer
첫번째로 Mapper를 살펴보자.
package hadoop_test;
import java.io.IOException;
import java.util.StringTokenizer;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;
public class WordCountMapper extends
Mapper<LongWritable, Text, Text, IntWritable>{
private final static IntWritable one = new IntWritable(1);
private Text word = new Text();
public void map(LongWritable 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);
}
}
}
알고리즘
1. 입력파라미터의 값인 문장을 공백 단위로 구분해 글자 수를 계산
2. 구분된 글자는 즉시 출력 파라미터에 추가. 글자 수를 1로 설정. ex) hi bob = 2
1]
public class WordCountMapper extends Mapper<LongWritable, Text,Text, IntWritable>
위 클래스는 Mapper 를 상속한다. 그대로 사용할 수 있지만 대부분 오버라이딩 한다.
Mapper.java는 Hadoop/src/mapred/org/apache/hadoop/mapreduce 에 정의되어 있다.
또한 제네릭 파라미터를 사용한다. 제네릭을 모른다?https://wikidocs.net/268
Mapper 코드는 입력 파일을 <Key, Value> 쌍으로 읽고 키 값 쌍을 내 보낸다.
순서대로 Mapper<입력 키 타입, 입력 값 타입, 출력 키 타입, 출력 값 타입>이다.
위 코를 해석하면 Mapper<Long, String, String Integer>이다.
어째서 LongWritable -> Long, IntWritable-> Integer 이냐면, 맵리듀스는 네크워크 통신을 위한 최적화된 객체로 WritableComparable 인터페이스를 제공한다. 이를 통해 데이터 타입을 Wrapping을 하기 때문에 자료형의 클래스가 다르다. WritableComparable를 직접 구현하여 쓸 수 도 있다.
2]
private final static IntWritable one = new IntWritable(1);
private Text word = new Text();
word는 키 , one은 값으로 사용한다. 예를 들어 "hi my hi "를 wordcount 하면 hi:2 my:1로 출력해야 한다. 글자 수는 1이여야 하므로 one을 final static으로 지정했다.
3]
public void map(LongWritable key, Text value, Context context)
Mapper class스에도 정의되어 있는 method다. 각 인자는 <입력 키 타입, 입력 값 타입, Context 객체>이다. 이때 첫번째와 두번째 인자는 매퍼 클래스를 상속 받을 때와 동일한 타입이여야 한다. 즉 1]과 같이 데이터 타입을 Long, String으로 해야한다.
세번째 인자는 맵리듀스와 통신하면서 출력데이터, 모니터링에 필요한 상태값 등을 갱신하는 역할을 한다. Mapper.java 클래스에 Context클래스가 정의되어 있으며 생성자를 보면 InputFormat라는 추상클래스가 제공하는 RecordReader를 볼 수 있다. 이 때문에 입력 스플릿이 키와 값의 레코드로 맵 메서드의 파라미터로 전달 될 수 있는 것이다.
4] StringTokenizer
StringTokenizer를 통해 공백 단위로 구분된 String값을 순회한다.
클래스에 대한 정보는 https://docs.oracle.com/javase/7/docs/api/