사막 데이터 탐험 퀘스트

HadoopBeginner
지금 연습하기

소개

광활한 사막 황무지에서 한 상인이 뜨거운 모래 아래 숨겨진 미스터리를 풀기 위해 위험한 여정을 시작합니다. 상인의 목표는 고대 유물과 인공물을 발굴하여 오랫동안 잊혀진 문명의 비밀을 밝혀내는 것입니다. 그러나 사막에 묻힌 방대한 양의 데이터는 강력한 도전 과제를 제시하며, Hadoop MapReduce 의 힘을 빌려 정보를 효과적으로 처리하고 분석해야 합니다.

Mapper 구현

이 단계에서는 사막 발굴에서 얻은 원시 데이터를 처리하기 위해 Mapper 클래스를 생성합니다. 우리의 목표는 데이터에서 관련 정보를 추출하고 Reducer 에 의한 추가 분석을 위해 준비하는 것입니다.

su - hadoop 명령을 사용하여 hadoop 사용자로 전환하고 자동으로 /home/hadoop 디렉토리로 이동합니다. 이 때, ls . 명령을 사용하여 데이터 파일 data*.txt를 확인합니다. 그런 다음 아래 코드에 따라 해당 디렉토리에 ArtifactMapper.java 파일을 생성하고 채웁니다.

import java.io.IOException;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;

public class ArtifactMapper extends Mapper<LongWritable, Text, Text, LongWritable> {

    private final static LongWritable ONE = new LongWritable(1);
    private Text word = new Text();

    @Override
    public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
        // Split the line into words
        String[] tokens = value.toString().split("\\s+");

        // Emit each word with a count of 1
        for (String token : tokens) {
            word.set(token);
            context.write(word, ONE);
        }
    }
}

ArtifactMapper 클래스에서 Hadoop 에서 제공하는 Mapper 클래스를 확장합니다. map 메서드는 각 입력 키 - 값 쌍을 처리하도록 재정의됩니다.

  1. 입력 키는 입력 줄의 바이트 오프셋을 나타내는 LongWritable이며, 입력 값은 입력 파일의 텍스트 줄을 포함하는 Text 객체입니다.
  2. map 메서드는 split 메서드와 하나 이상의 공백 문자를 일치시키는 정규 표현식 "\\s+"를 사용하여 입력 줄을 개별 단어로 분할합니다.
  3. 각 단어에 대해 map 메서드는 Text 객체를 생성하고 해당 단어를 키로 내보내며, 해당 단어의 수를 나타내는 값으로 상수 LongWritable1을 함께 내보냅니다.

Reducer 구현

이 단계에서는 Mapper 에서 내보낸 데이터를 집계하기 위해 Reducer 클래스를 생성합니다. Reducer 는 각 단어의 발생 횟수를 계산하고 최종 출력을 생성합니다.

다음 코드 내용에 따라 /home/hadoop 디렉토리에 ArtifactReducer.java 파일을 생성하고 채웁니다.

import java.io.IOException;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;

public class ArtifactReducer extends Reducer<Text, LongWritable, Text, LongWritable> {

    @Override
    public void reduce(Text key, Iterable<LongWritable> values, Context context)
            throws IOException, InterruptedException {
        long sum = 0;
        for (LongWritable value : values) {
            sum += value.get();
        }
        context.write(key, new LongWritable(sum));
    }
}

ArtifactReducer 클래스에서 Hadoop 에서 제공하는 Reducer 클래스를 확장합니다. reduce 메서드는 각 키와 관련된 값을 집계하도록 재정의됩니다.

  1. 입력 키는 단어를 나타내는 Text 객체이며, 입력 값은 Mappers 에서 내보낸 해당 단어의 수를 나타내는 LongWritable 객체의 Iterable입니다.
  2. reduce 메서드는 값을 반복하고 주어진 단어에 대한 모든 수의 합계를 계산합니다.
  3. 그런 다음 reduce 메서드는 context.write를 사용하여 단어를 키로, 총 수를 값으로 내보냅니다.

Driver 생성

이 단계에서는 MapReduce 작업을 조율하기 위해 Driver 클래스를 생성합니다. Driver 는 작업을 구성하고, 입력 및 출력 경로를 지정하며, Hadoop 클러스터에 작업을 제출합니다.

다음 코드 내용에 따라 /home/hadoop 디렉토리에 ArtifactDriver.java 파일을 생성하고 채웁니다.

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
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 ArtifactDriver {

    public static void main(String[] args) throws Exception {
        Configuration conf = new Configuration();
        Job job = Job.getInstance(conf, "Artifact Word Count");

        // Specify the job's jar file by class
        job.setJarByClass(ArtifactDriver.class);

        // Set the Mapper and Reducer classes
        job.setMapperClass(ArtifactMapper.class);
        job.setReducerClass(ArtifactReducer.class);

        // Set the output key and value types
        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(LongWritable.class);

        // Set the input and output paths
        FileInputFormat.addInputPath(job, new Path(args[0]));
        FileOutputFormat.setOutputPath(job, new Path(args[1]));

        // Submit the job and wait for completion
        System.exit(job.waitForCompletion(true) ? 0 : 1);
    }
}

ArtifactDriver 클래스에서 MapReduce 작업을 생성하고 ArtifactMapperArtifactReducer 클래스를 실행하도록 구성합니다.

  1. main 메서드는 새 Configuration 객체와 사용자 지정 이름 "Artifact Word Count"를 가진 Job 객체를 생성합니다.
  2. setMapperClasssetReducerClass 메서드는 작업에 사용할 Mapper 및 Reducer 클래스를 지정하는 데 사용됩니다.
  3. setOutputKeyClasssetOutputValueClass 메서드는 작업의 출력 키 및 값 유형을 지정하는 데 사용됩니다.
  4. FileInputFormat.addInputPath 메서드는 작업의 입력 경로를 지정하는 데 사용되며, 이는 첫 번째 명령줄 인수로 사용됩니다.
  5. FileOutputFormat.setOutputPath 메서드는 작업의 출력 경로를 지정하는 데 사용되며, 이는 두 번째 명령줄 인수로 사용됩니다.
  6. job.waitForCompletion 메서드는 작업을 제출하고 완료될 때까지 기다리는 데 사용됩니다. 작업이 성공하면 프로그램은 상태 코드 0 으로 종료되고, 실패하면 1 로 종료됩니다.

Job 컴파일 및 실행

이 단계에서는 Java 클래스를 컴파일하고 Hadoop 클러스터에서 MapReduce 작업을 실행합니다.

먼저, Java 클래스를 컴파일해야 합니다.

javac -source 8 -target 8 -classpath $HADOOP_HOME/share/hadoop/common/hadoop-common-3.3.6.jar:$HADOOP_HOME/share/hadoop/mapreduce/hadoop-mapreduce-client-core-3.3.6.jar:. *.java

이 명령은 Java 클래스를 컴파일하고 컴파일된 .class 파일을 현재 디렉토리에 배치합니다. -classpath 옵션은 Hadoop 클래스를 사용하는 코드를 컴파일하는 데 필요한 Hadoop 라이브러리 경로를 포함합니다. -source-target은 hadoop 의 java 버전과 일치하도록 Java 소스 및 대상 바이트코드 버전을 지정하는 데 사용되는 매개변수입니다.

다음으로, jar 명령을 사용하여 class 파일을 패키징합니다.

jar -cvf Artifact.jar *.class

마지막으로, MapReduce 작업을 실행할 수 있으며, 사막에 대한 모든 데이터는 이미 /input HDFS 디렉토리에 저장되어 있습니다.

hadoop jar Artifact.jar ArtifactDriver /input /output

명령을 실행하면 MapReduce 작업의 진행 상황을 나타내는 로그가 표시됩니다. 작업이 완료되면 /output HDFS 디렉토리에서 출력 파일을 찾을 수 있습니다. 그리고 다음 명령을 사용하여 결과를 볼 수 있습니다.

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

요약

축하합니다! Hadoop MapReduce 작업을 위한 Mapper 및 Reducer 코딩 과정을 성공적으로 탐구했습니다. 고대 유물을 찾는 사막 상인과 관련된 시나리오를 통해 광대한 사막 데이터를 분석하기 위해 Hadoop MapReduce 의 강력한 기능을 활용했습니다. ArtifactMapper 클래스를 구현하여 관련 데이터를 추출하고, ArtifactReducer 클래스를 통해 Mapper 출력을 집계했습니다. ArtifactDriver 클래스를 사용하여 프로세스를 조율함으로써 이해도를 더욱 공고히 했습니다. 전체 과정에서 모범 사례, 완전한 코드 예제 및 검증 확인에 중점을 두었습니다. 이 실습 경험은 Hadoop MapReduce 에 대한 이해를 심화시키고 효과적인 학습 경험 설계를 강조했습니다.