分散キャッシュの古代の知恵

HadoopBeginner
オンラインで実践に進む

はじめに

失われた文明の古代遺跡の中で、現代の探検隊が知識と賢明さの神に捧げられた隠された神殿に出くわしました。神殿の壁には、古代の司祭が使用した高度なデータ処理システムの秘密を秘めた精巧な象形文字が飾られていました。

探検隊の一人である熟練した Hadoop エンジニアが、大司祭の役割を務め、象形文字を解読して神殿の謎を解き明かしました。目的は、古代の司祭が何世紀も前に行ったように、Hadoop の分散キャッシュの力を活用して大規模なデータセットを効率的に処理するため、古代のデータ処理システムを再構築することでした。

データセットとコードを準備する

このステップでは、古代のデータ処理システムをシミュレートするために必要なファイルとコードをセットアップします。

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

su - hadoop

distributed-cache-lab という新しいディレクトリを作成し、その中に移動します。

mkdir distributed-cache-lab
cd distributed-cache-lab

次に、以下の内容を持つ ancient-texts.txt というテキストファイルを作成します。

The wisdom of the ages is eternal.
Knowledge is the path to enlightenment.
Embrace the mysteries of the universe.

このファイルは、処理したい古代のテキストを表します。

次に、以下のコードを持つ AncientTextAnalyzer.java という Java ファイルを作成します。

import java.io.BufferedReader;
import java.io.FileReader;
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;
import org.apache.hadoop.util.GenericOptionsParser;

public class AncientTextAnalyzer {

    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();
        String[] otherArgs = new GenericOptionsParser(conf, args).getRemainingArgs();
        if (otherArgs.length!= 2) {
            System.err.println("Usage: AncientTextAnalyzer <in> <out>");
            System.exit(2);
        }

        Job job = Job.getInstance(conf, "Ancient Text Analyzer");
        job.setJarByClass(AncientTextAnalyzer.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(otherArgs[0]));
        FileOutputFormat.setOutputPath(job, new Path(otherArgs[1]));

        System.exit(job.waitForCompletion(true)? 0 : 1);
    }
}

このコードは、入力ファイル内の各単語の出現回数をカウントする単純な MapReduce プログラムです。このコードを使って、Hadoop における分散キャッシュの使い方を示します。

コードをコンパイルしてパッケージ化する

このステップでは、Java コードをコンパイルして、展開用の JAR ファイルを作成します。

まず、クラスパスに Hadoop コア JAR ファイルがあることを確認してください。Apache Hadoop ウェブサイトからダウンロードするか、Hadoop インストールに含まれるものを使用できます。

AncientTextAnalyzer.java ファイルをコンパイルします。

javac -source 8 -target 8 -classpath "/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/*" AncientTextAnalyzer.java

次に、コンパイル済みのクラスファイルで JAR ファイルを作成します。

jar -cvf ancient-text-analyzer.jar AncientTextAnalyzer*.class

分散キャッシュを使って MapReduce ジョブを実行する

このステップでは、MapReduce ジョブを実行し、分散キャッシュを利用してクラスタ内のすべてのノードに入力ファイルを提供します。

まず、入力ファイル ancient-texts.txt を Hadoop 分散ファイルシステム(HDFS)にコピーします。

hadoop fs -mkdir /input
hadoop fs -put ancient-texts.txt /input/ancient-texts.txt

次に、分散キャッシュオプションを使って MapReduce ジョブを実行します。

hadoop jar ancient-text-analyzer.jar AncientTextAnalyzer -files ancient-texts.txt /input/ancient-texts.txt /output

このコマンドは、-files オプションを使って ancient-texts.txt ファイルをクラスタ内のすべてのノードに配布して、AncientTextAnalyzer MapReduce ジョブを実行します。入力パスは /input/ancient-texts.txt で、出力パスは /output です。

ジョブが完了した後、出力を確認できます。

hadoop fs -cat /output/part-r-00000

以下のような単語カウントの出力が表示されるはずです。

Embrace 1
Knowledge       1
The     1
ages    1
enlightenment.  1
eternal.        1
is      2
mysteries       1
of      2
path    1
the     4
to      1
universe.       1
wisdom  1

まとめ

この実験では、古代のテキスト分析システムを実装することで、Hadoop の分散キャッシュ機能の威力を探求しました。分散キャッシュを活用することで、クラスタ内のすべてのノードに入力ファイルを効率的に配布し、並列処理を可能にし、ネットワークを越えたデータ転送のオーバーヘッドを削減することができました。

この実践的な経験を通じて、Hadoop の分散キャッシュが分散コンピューティング環境におけるデータ処理をどのように最適化できるかについて、より深い理解を得ました。クラスタ全体で頻繁にアクセスされるデータをキャッシュすることで、特に大規模なデータセットや複雑な計算を扱う場合に、性能を大幅に向上させ、ネットワークトラフィックを削減することができます。

また、この実験は、Hadoop MapReduce、Java プログラミング、および Hadoop クラスタ上でのジョブ実行に関する実践的な経験を提供しました。理論的な知識と実践的な練習の組み合わせにより、ビッグデータ処理の熟練度が向上し、より高度な Hadoop 関連のチャレンジに備えることができるようになりました。