소개
신비로운 야시장에서 화려한 가면을 쓴 매혹적인 인물이 붐비는 군중 속을 우아하게 움직입니다. 이 수수께끼의 가면 무용수는 비밀스러운 힘을 지닌 듯, 춤을 추며 혼란스러운 노점들을 질서 정연하게 정렬합니다. 여러분의 목표는 Hadoop Shuffle Comparable 기술을 마스터하여 이 놀라운 재능 뒤에 숨겨진 미스터리를 푸는 것입니다.
신비로운 야시장에서 화려한 가면을 쓴 매혹적인 인물이 붐비는 군중 속을 우아하게 움직입니다. 이 수수께끼의 가면 무용수는 비밀스러운 힘을 지닌 듯, 춤을 추며 혼란스러운 노점들을 질서 정연하게 정렬합니다. 여러분의 목표는 Hadoop Shuffle Comparable 기술을 마스터하여 이 놀라운 재능 뒤에 숨겨진 미스터리를 푸는 것입니다.
이 단계에서는 입력 데이터를 처리하고 키 - 값 쌍을 내보내기 위해 사용자 정의 Mapper 클래스를 생성합니다. 키는 각 단어의 첫 번째 문자와 단어의 길이로 구성된 복합 키 (composite key) 가 됩니다. 값은 단어 자체입니다.
먼저 사용자를 hadoop으로 변경한 다음 hadoop 사용자의 홈 디렉토리로 전환합니다.
su - hadoop
그런 다음 Mapper 클래스에 대한 Java 파일을 생성합니다.
touch /home/hadoop/WordLengthMapper.java
WordLengthMapper.java 파일에 다음 코드를 추가합니다.
import java.io.IOException;
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 WordLengthMapper extends Mapper<LongWritable, Text, CompositeKey, Text> {
private CompositeKey compositeKey = new CompositeKey();
public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
String line = value.toString();
String[] words = line.split("\\s+");
for (String word : words) {
compositeKey.setFirstChar(word.charAt(0));
compositeKey.setLength(word.length());
context.write(compositeKey, new Text(word));
}
}
}
위 코드에서 Hadoop MapReduce API 의 Mapper 클래스를 확장하는 WordLengthMapper 클래스를 생성합니다. map 메서드는 LongWritable 키 (입력 줄의 바이트 오프셋을 나타냄) 와 Text 값 (입력 줄 자체) 을 받습니다. 그런 다음 입력 줄을 개별 단어로 분할하고, 각 단어에 대한 CompositeKey 객체 (단어의 첫 번째 문자와 길이를 포함) 를 생성하고, CompositeKey를 키로, 단어를 값으로 내보냅니다.
이 단계에서는 Hadoop MapReduce API 의 WritableComparable 인터페이스를 구현하는 사용자 정의 CompositeKey 클래스를 생성합니다. 이 클래스는 MapReduce 작업에서 키로 사용되어 각 단어의 첫 번째 문자와 길이를 기준으로 데이터를 정렬하고 그룹화할 수 있습니다.
먼저 CompositeKey 클래스에 대한 Java 파일을 생성합니다.
touch /home/hadoop/CompositeKey.java
그런 다음 CompositeKey.java 파일에 다음 코드를 추가합니다.
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import org.apache.hadoop.io.WritableComparable;
public class CompositeKey implements WritableComparable<CompositeKey> {
private char firstChar;
private int length;
public CompositeKey() {
}
public void setFirstChar(char firstChar) {
this.firstChar = firstChar;
}
public char getFirstChar() {
return firstChar;
}
public void setLength(int length) {
this.length = length;
}
public int getLength() {
return length;
}
@Override
public void write(DataOutput out) throws IOException {
out.writeChar(firstChar);
out.writeInt(length);
}
@Override
public void readFields(DataInput in) throws IOException {
firstChar = in.readChar();
length = in.readInt();
}
@Override
public int compareTo(CompositeKey other) {
int cmp = Character.compare(firstChar, other.firstChar);
if (cmp != 0) {
return cmp;
}
return Integer.compare(length, other.length);
}
@Override
public int hashCode() {
return firstChar + length;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof CompositeKey) {
CompositeKey other = (CompositeKey) obj;
return firstChar == other.firstChar && length == other.length;
}
return false;
}
@Override
public String toString() {
return firstChar + ":" + length;
}
}
위 코드에서 WritableComparable 인터페이스를 구현하는 CompositeKey 클래스를 생성합니다. 이 클래스는 firstChar (단어의 첫 번째 문자) 와 length (단어의 길이) 의 두 필드를 갖습니다. 이 클래스는 이러한 필드에 대한 getter 및 setter 메서드와 WritableComparable 인터페이스에 필요한 write, readFields, compareTo, hashCode, equals, 및 toString 메서드의 구현을 제공합니다.
compareTo 메서드는 MapReduce 작업에서 키가 정렬되는 방식을 정의하므로 특히 중요합니다. 구현에서 먼저 두 키의 firstChar 필드를 비교합니다. 다르면 해당 비교의 결과를 반환합니다. firstChar 필드가 같으면 length 필드를 비교합니다.
이 단계에서는 Mapper 에서 내보낸 키 - 값 쌍을 처리하고 최종 출력을 생성하기 위해 사용자 정의 Reducer 클래스를 생성합니다.
먼저 Reducer 클래스에 대한 Java 파일을 생성합니다.
touch /home/hadoop/WordLengthReducer.java
그런 다음 WordLengthReducer.java 파일에 다음 코드를 추가합니다.
import java.io.IOException;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;
public class WordLengthReducer extends Reducer<CompositeKey, Text, CompositeKey, Text> {
public void reduce(CompositeKey key, Iterable<Text> values, Context context) throws IOException, InterruptedException {
StringBuilder sb = new StringBuilder();
for (Text value : values) {
sb.append(value.toString()).append(", ");
}
sb.setLength(sb.length() - 2);
context.write(key, new Text(sb.toString()));
}
}
위 코드에서 Hadoop MapReduce API 의 Reducer 클래스를 확장하는 WordLengthReducer 클래스를 생성합니다. reduce 메서드는 CompositeKey 키 (단어의 첫 번째 문자와 길이를 포함) 와 Text 값의 Iterable(키와 일치하는 단어) 을 받습니다.
reduce 메서드 내에서 키와 일치하는 모든 단어를 쉼표로 구분된 문자열로 연결합니다. StringBuilder를 사용하여 출력을 효율적으로 구성하고, 키 - 값 쌍을 출력에 쓰기 전에 후행 쉼표와 공백을 제거합니다.
이 단계에서는 MapReduce 작업을 구성하고 실행하기 위한 Driver 클래스를 생성합니다.
먼저 Driver 클래스에 대한 Java 파일을 생성합니다.
touch /home/hadoop/WordLengthDriver.java
그런 다음 WordLengthDriver.java 파일에 다음 코드를 추가합니다.
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
public class WordLengthDriver {
public static void main(String[] args) throws Exception {
if (args.length != 2) {
System.err.println("Usage: WordLengthDriver <input> <output>");
System.exit(1);
}
Configuration conf = new Configuration();
Job job = Job.getInstance(conf, "Word Length");
job.setJarByClass(WordLengthDriver.class);
job.setMapperClass(WordLengthMapper.class);
job.setReducerClass(WordLengthReducer.class);
job.setOutputKeyClass(CompositeKey.class);
job.setOutputValueClass(Text.class);
FileInputFormat.addInputPath(job, new Path(args[0]));
FileOutputFormat.setOutputPath(job, new Path(args[1]));
System.exit(job.waitForCompletion(true) ? 0 : 1);
}
}
위 코드에서 MapReduce 작업의 진입점 역할을 하는 WordLengthDriver 클래스를 생성합니다. main 메서드는 작업에 대한 입력 경로와 출력 경로의 두 가지 명령줄 인수를 받습니다.
main 메서드 내에서 새 Configuration 객체와 새 Job 객체를 생성합니다. 매퍼 및 리듀서 클래스, 출력 키 및 값 클래스, 입력 및 출력 경로를 설정하여 작업을 구성합니다.
마지막으로 작업을 제출하고 완료될 때까지 기다립니다. 작업이 성공적으로 완료되면 상태 코드 0 으로 종료하고, 그렇지 않으면 상태 코드 1 로 종료합니다.
작업을 실행하려면 다음 명령을 사용할 수 있습니다.
javac -source 8 -target 8 -classpath "/home/hadoop/:/home/hadoop/hadoop/share/hadoop/common/hadoop-common-3.3.6.jar:/home/hadoop/hadoop/share/hadoop/mapreduce/hadoop-mapreduce-client-core-3.3.6.jar:/home/hadoop/hadoop/share/hadoop/common/lib/*" -d /home/hadoop /home/hadoop/WordLengthMapper.java /home/hadoop/CompositeKey.java /home/hadoop/WordLengthReducer.java /home/hadoop/WordLengthDriver.java
jar cvf word-length.jar *.class
hadoop jar word-length.jar WordLengthDriver /input /output
마지막으로 다음 명령을 실행하여 결과를 확인할 수 있습니다.
hadoop fs -cat /output/*
예시 출력:
A:3 Amr
A:6 AADzCv
A:10 AlGyQumgIl
...
h:7 hgQUIhA
h:8 hyrjMGbY, hSElGKux
h:10 hmfHJjCkwB
...
z:6 zkpRCN
z:8 zfMHRbtk
z:9 zXyUuLHma
이 랩에서는 첫 번째 문자와 길이를 기준으로 단어를 그룹화하는 MapReduce 작업을 구현하여 Hadoop Shuffle Comparable 의 개념을 탐구했습니다. 복합 키를 사용하여 키 - 값 쌍을 내보내는 사용자 정의 Mapper, WritableComparable 인터페이스를 구현하는 사용자 정의 CompositeKey 클래스, 동일한 키를 가진 단어를 연결하는 Reducer, 작업을 구성하고 실행하는 Driver 클래스를 생성했습니다.
이 랩을 통해 Hadoop MapReduce 프레임워크와 분산 컴퓨팅에서 사용자 정의 데이터 유형 및 정렬의 중요성에 대한 더 깊은 이해를 얻었습니다. Hadoop Shuffle Comparable 을 마스터함으로써, 우리는 데이터 처리 및 분석을 위한 효율적인 알고리즘을 설계하여, 혼란스러운 야시장의 노점을 정렬하는 수수께끼의 가면 무용수처럼 빅 데이터의 힘을 열 수 있습니다.