Hadoop Shuffle Combiner

HadoopHadoopBeginner
今すぐ練習

💡 このチュートリアルは英語版からAIによって翻訳されています。原文を確認するには、 ここをクリックしてください

はじめに

宇宙戦闘シミュレーションシステムにおけるデータ管理を担当する才能あるエンジニアであると想像してみてください。あなたの目標は、MapReduceプロセスにおいてHadoop Shuffle Combinerテクニックを実装することにより、システムのパフォーマンスを最適化することです。Combinerを活用することで、シミュレーション中のデータ処理におけるネットワークトラフィックを削減し、全体的な効率を向上させることを目指しています。


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL hadoop(("Hadoop")) -.-> hadoop/HadoopMapReduceGroup(["Hadoop MapReduce"]) hadoop(("Hadoop")) -.-> hadoop/HadoopYARNGroup(["Hadoop YARN"]) hadoop(("Hadoop")) -.-> hadoop/HadoopHiveGroup(["Hadoop Hive"]) hadoop/HadoopMapReduceGroup -.-> hadoop/setup_jobs("Setting up MapReduce Jobs") hadoop/HadoopMapReduceGroup -.-> hadoop/mappers_reducers("Coding Mappers and Reducers") hadoop/HadoopMapReduceGroup -.-> hadoop/shuffle_combiner("Shuffle Combiner") hadoop/HadoopYARNGroup -.-> hadoop/yarn_jar("Yarn Commands jar") hadoop/HadoopHiveGroup -.-> hadoop/process("Process Control Function") hadoop/HadoopHiveGroup -.-> hadoop/aggregating("Aggregating Function") hadoop/HadoopHiveGroup -.-> hadoop/udf("User Defined Function") subgraph Lab Skills hadoop/setup_jobs -.-> lab-271904{{"Hadoop Shuffle Combiner"}} hadoop/mappers_reducers -.-> lab-271904{{"Hadoop Shuffle Combiner"}} hadoop/shuffle_combiner -.-> lab-271904{{"Hadoop Shuffle Combiner"}} hadoop/yarn_jar -.-> lab-271904{{"Hadoop Shuffle Combiner"}} hadoop/process -.-> lab-271904{{"Hadoop Shuffle Combiner"}} hadoop/aggregating -.-> lab-271904{{"Hadoop Shuffle Combiner"}} hadoop/udf -.-> lab-271904{{"Hadoop Shuffle Combiner"}} end

Mapperを記述する

このステップでは、入力データを処理して中間のキー-値ペアを生成するMapperクラスを記述します。

端末を開き、以下の手順に従って始めましょう。

ユーザをhadoopに変更し、次にhadoopユーザのホームディレクトリに切り替えます。

su - hadoop

Mapperクラス用のJavaファイルを作成します。

nano /home/hadoop/SpaceBattleMapper.java

次に、SpaceBattleMapper.javaファイルに以下のコードを追加します。

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

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

    @Override
    protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
        // 入力行を単語に分割する
        String[] words = value.toString().split("\\s+");
        // 各単語に対してキー-値ペアを生成する
        for (String w : words) {
            word.set(w);
            context.write(word, one);
        }
    }
}

ヒント:右側のプロンプトボックスからコードをコピーし、Ctrl + Shift + Vで開いているnanoエディタに貼り付けることができます。nanoエディタからのプロンプトが表示されたときに、Ctrl + Oを押してファイルを保存し、Enterを押して確認します。最後に、Ctrl + Xを使ってエディタを終了します。

SpaceBattleMapperクラスは、HadoopフレームワークのMapperクラスを拡張しています。これは、キー-値ペア形式の入力データを処理するために使用されます。ここで、キーは入力ファイル内の行のバイトオフセットを表すLongWritableで、値はテキストの行を表すTextオブジェクトです。

このクラスは2つのプライベートフィールドを定義しています。

  • one:定数値1を持つIntWritableオブジェクト。これは生成されるキー-値ペアの値として使用されます。
  • word:入力行から抽出された各単語を格納するためのTextオブジェクト。

mapメソッドは、特定のマッピングロジックを提供するためにオーバーライドされています。

  • 入力のText値を文字列に変換し、空白を基準に単語に分割します。
  • 配列内の各単語に対して、wordオブジェクトをその単語に設定し、キーとしてその単語と値としてoneを持つキー-値ペアを生成します。これはcontext.writeメソッドを使用して行われます。

このMapperクラスは、入力データ内の各単語に対して、キーとしてその単語と値として整数1を持つキー-値ペアを生成するように設計されています。この設定は、データセット内の各単語の出現回数をカウントすることを目的とする単語カウントアプリケーションで一般的に使用されます。

Combinerを実装する

このステップでは、データのシャッフルの前にローカルな集約を行うためにCombinerクラスを実装します。

Combinerクラス用のJavaファイルを作成します。

nano /home/hadoop/SpaceBattleCombiner.java

次に、SpaceBattleCombiner.javaファイルに以下のコードを追加します。

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

public class SpaceBattleCombiner extends Reducer<Text, IntWritable, Text, IntWritable> {
    @Override
    protected void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
        int sum = 0;
        // 各キーの値を合計する
        for (IntWritable val : values) {
            sum += val.get();
        }
        // キーとその値の合計を出力する
        context.write(key, new IntWritable(sum));
    }
}

SpaceBattleCombinerクラスは、HadoopフレームワークのReducerクラスを拡張しています。これは、MapReduceプロセスにおいてCombinerとして使用され、Mapperによって生成された中間のキー-値ペアのローカルな集約を行います。

このクラスは、特定のCombinerロジックを提供するためにreduceメソッドをオーバーライドしています。

  • このメソッドは、Text型のキーとIntWritable型の値の反復可能オブジェクトを入力として受け取ります。キーは単語を表し、反復可能オブジェクトはその単語の出現回数を含んでいます。
  • このメソッドは値を反復処理し、それらを合計して単語の合計数を取得します。
  • 最後に、このメソッドはcontext.writeメソッドを使用して、キーとして単語と値として合計数を持つキー-値ペアを出力します。

SpaceBattleCombinerの目的は、データがネットワークを介してReducerにシャッフルされる前に、各単語のカウントのローカルな集約を行うことです。これにより、MapperとReducerのフェーズ間で転送されるデータ量が削減され、MapReduceジョブの効率が向上します。

Reducerを実装する

このステップでは、キー-値ペアの最終的な集約を行うためにReducerクラスを実装します。

  1. Reducerクラス用のJavaファイルを作成します。
nano /home/hadoop/SpaceBattleReducer.java

次に、SpaceBattleReducer.javaファイルに以下のコードを追加します。

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

public class SpaceBattleReducer extends Reducer<Text, IntWritable, Text, IntWritable> {
    @Override
    protected void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
        int sum = 0;
        for (IntWritable val : values) {
            sum += val.get();
        }
        context.write(key, new IntWritable(sum));
    }
}

SpaceBattleReducerクラスは、HadoopフレームワークのReducerクラスを拡張しています。これは、Mapperによって生成され、任意にCombinerによって処理された中間のキー-値ペアの最終的な集約を行うために使用されます。

このクラスは、特定のReducerロジックを提供するためにreduceメソッドをオーバーライドしています。

  • このメソッドは、Text型のキーとIntWritable型の値の反復可能オブジェクトを入力として受け取ります。キーは単語を表し、反復可能オブジェクトはその単語の出現回数を含んでいます。
  • このメソッドは値を反復処理し、それらを合計して単語の合計数を取得します。
  • 最後に、このメソッドはcontext.writeメソッドを使用して、キーとして単語と値として合計数を持つキー-値ペアを出力します。

SpaceBattleReducerは、すべてのMapper出力にわたる各単語のカウントを合計することで、データの最終的な集約を行います。これにより、入力データ内の各単語の最終的な出現回数が提供されます。

Driverを記述する

このステップでは、MapReduceジョブを管理するJavaファイルを作成します。これには、ジョブの設定を行い、Mapper、Combiner、Reducerクラスを指定することが含まれます。

Driverクラス用のJavaファイルを作成します。

nano /home/hadoop/SpaceBattleDriver.java

次に、SpaceBattleDriver.javaファイルに以下のコードを追加します。

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.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;

public class SpaceBattleDriver {
    public static void main(String[] args) throws Exception {
        Configuration conf = new Configuration();
        Job job = Job.getInstance(conf, "Space Battle Simulation");
        job.setJarByClass(SpaceBattleDriver.class);
        job.setMapperClass(SpaceBattleMapper.class);
        job.setCombinerClass(SpaceBattleCombiner.class);
        job.setReducerClass(SpaceBattleReducer.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);
    }
}

SpaceBattleDriverクラスは、宇宙戦闘シミュレーションのMapReduceジョブを構成して実行する責任があります。

  • このクラスは、新しいConfigurationオブジェクトとこの設定を持つJobインスタンスを作成することから始まります。ジョブには識別用の名前「Space Battle Simulation」が付けられています。
  • setJarByClassメソッドにSpaceBattleDriverクラスを渡して、ジョブに必要なクラスが含まれるjarファイルを設定します。
  • setMapperClasssetCombinerClasssetReducerClassメソッドを使用して、それぞれマッピング、結合、削減タスクを実行するクラスを指定します。
  • setOutputKeyClasssetOutputValueClassメソッドで、出力キーと値の型を定義します。この場合、それぞれText型とIntWritable型です。
  • FileInputFormat.addInputPathFileOutputFormat.setOutputPathメソッドで、入力データと出力データのパスを設定します。これらのパスは、mainメソッドにコマンドライン引数として渡されます。
  • 最後に、job.waitForCompletionメソッドを呼び出してジョブを送信し、完了を待ちます。ジョブが正常に完了するとtrueを返し、そうでなければfalseを返します。ジョブが成功するとプログラムはステータスコード0で終了し、失敗すると1で終了します。

このDriverクラスは、MapReduceジョブのすべてのコンポーネントを結び付け、ジョブを実行するエントリポイントです。

まとめ

この実験では、宇宙戦闘シミュレーションのシナリオでHadoop Shuffle Combiner技術の実装を学びました。Mapper、Combiner、Reducer、Driverクラスを作成する手順に従うことで、Hadoop MapReduce環境におけるデータ処理の最適化に関する実践的な経験を得ました。この実験の目的は、ビッグデータ処理タスクにおけるネットワークオーバーヘッドの削減と計算効率の向上に関する理解を深めることでした。