Hadoop を使った恐竜データの融合

HadoopHadoopBeginner
今すぐ練習

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

はじめに

恐竜の時代に、勇敢な恐竜ハンターであるアレックスは、これらの史前生物の秘密を解き明かす刺激的なミッションに乗り出します。アレックスの目標は、さまざまなソースから貴重なデータを収集し、高度な分析を行って、さまざまな恐竜種の行動、食性、進化についての洞察を得ることです。

これを達成するために、アレックスは Hadoop MapReduce の力とその効率的な結合操作の能力を活用する必要があります。複数のソースからのデータを結合することで、アレックスは恐竜の化石、その地質学的な場所、および環境条件に関する情報を組み合わせて、恐竜の世界の包括的な画像を描くことができます。


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL hadoop(("Hadoop")) -.-> hadoop/HadoopHDFSGroup(["Hadoop HDFS"]) hadoop(("Hadoop")) -.-> hadoop/HadoopMapReduceGroup(["Hadoop MapReduce"]) hadoop(("Hadoop")) -.-> hadoop/HadoopHiveGroup(["Hadoop Hive"]) hadoop/HadoopHDFSGroup -.-> hadoop/hdfs_setup("HDFS Setup") hadoop/HadoopHDFSGroup -.-> hadoop/fs_cat("FS Shell cat") hadoop/HadoopHDFSGroup -.-> hadoop/fs_ls("FS Shell ls") hadoop/HadoopHDFSGroup -.-> hadoop/fs_mkdir("FS Shell mkdir") hadoop/HadoopHDFSGroup -.-> hadoop/fs_put("FS Shell copyToLocal/put") hadoop/HadoopMapReduceGroup -.-> hadoop/mappers_reducers("Coding Mappers and Reducers") hadoop/HadoopMapReduceGroup -.-> hadoop/implement_join("Implementing Join Operation") hadoop/HadoopHiveGroup -.-> hadoop/import_export_data("Importing and Exporting Data") hadoop/HadoopHiveGroup -.-> hadoop/join("join Usage") subgraph Lab Skills hadoop/hdfs_setup -.-> lab-288979{{"Hadoop を使った恐竜データの融合"}} hadoop/fs_cat -.-> lab-288979{{"Hadoop を使った恐竜データの融合"}} hadoop/fs_ls -.-> lab-288979{{"Hadoop を使った恐竜データの融合"}} hadoop/fs_mkdir -.-> lab-288979{{"Hadoop を使った恐竜データの融合"}} hadoop/fs_put -.-> lab-288979{{"Hadoop を使った恐竜データの融合"}} hadoop/mappers_reducers -.-> lab-288979{{"Hadoop を使った恐竜データの融合"}} hadoop/implement_join -.-> lab-288979{{"Hadoop を使った恐竜データの融合"}} hadoop/import_export_data -.-> lab-288979{{"Hadoop を使った恐竜データの融合"}} hadoop/join -.-> lab-288979{{"Hadoop を使った恐竜データの融合"}} end

環境とデータのセットアップ

このステップでは、必要な環境をセットアップし、結合操作に使用するデータを準備します。

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

su - hadoop

ファイルを保存するための新しいディレクトリ join-lab を作成します。

mkdir join-lab
cd join-lab

次に、2 つのデータファイル dinosaurs.txtlocations.txt を作成しましょう。これらのファイルには、それぞれ恐竜とその化石の場所に関する情報が含まれます。

次の内容で dinosaurs.txt を作成します。

trex,Tyrannosaurus Rex,carnivore
velociraptor,Velociraptor,carnivore
brachiosaurus,Brachiosaurus,herbivore
stegosaurus,Stegosaurus,herbivore

次の内容で locations.txt を作成します。

trex,North America
velociraptor,Asia
brachiosaurus,Africa
stegosaurus,North America

最後に、以下のコマンドを使用して join-labhdfs にアップロードします。

hadoop fs -mkdir -p /home/hadoop
hadoop fs -put /home/hadoop/join-lab /home/hadoop/

結合操作の実装

このステップでは、MapReduce ジョブを実装して、dinosaurs.txtlocations.txt ファイルに対して結合操作を行います。

/home/hadoop/join-lab ディレクトリに、以下の内容を持つ新しい Java ファイル JoinDinosaurs.java を作成します。

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

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

public class JoinDinosaurs {

    public static class JoinMapper extends Mapper<LongWritable, Text, Text, Text> {
        private final Text outKey = new Text();
        private final Text outValue = new Text();

        @Override
        protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
            String line = value.toString();
            String[] parts = line.split(",");

            if (parts.length == 2) { // locations.txt
                outKey.set(parts[0]);
                outValue.set("LOC:" + parts[1]);
            } else if (parts.length == 3) { // dinosaurs.txt
                outKey.set(parts[0]);
                outValue.set("DIN:" + parts[1] + "," + parts[2]);
            }

            context.write(outKey, outValue);
        }
    }

    public static class JoinReducer extends Reducer<Text, Text, Text, Text> {
        private final Text outValue = new Text();

        @Override
        protected void reduce(Text key, Iterable<Text> values, Context context) throws IOException, InterruptedException {
            Map<String, String> dinMap = new HashMap<>();
            StringBuilder locBuilder = new StringBuilder();

            for (Text value : values) {
                String valStr = value.toString();
                if (valStr.startsWith("DIN:")) {
                    dinMap.put("DIN", valStr.substring(4));
                } else if (valStr.startsWith("LOC:")) {
                    locBuilder.append(valStr.substring(4)).append(",");
                }

                if (locBuilder.length() > 0) {
                    locBuilder.deleteCharAt(locBuilder.length() - 1);
                }
            }

            StringBuilder outBuilder = new StringBuilder();
            for (Map.Entry<String, String> entry : dinMap.entrySet()) {
                outBuilder.append(entry.getValue()).append("\t").append(locBuilder.toString().trim());
            }

            outValue.set(outBuilder.toString());
            context.write(key, outValue);
        }
    }

    public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
        if (args.length!= 2) {
            System.err.println("Usage: JoinDinosaurs <input_dir> <output_dir>");
            System.exit(1);
        }

        Job job = Job.getInstance();
        job.setJarByClass(JoinDinosaurs.class);
        job.setJobName("Join Dinosaurs");

        FileInputFormat.addInputPath(job, new Path(args[0]));
        FileOutputFormat.setOutputPath(job, new Path(args[1]));

        job.setMapperClass(JoinMapper.class);
        job.setReducerClass(JoinReducer.class);

        job.setInputFormatClass(TextInputFormat.class);
        job.setOutputFormatClass(TextOutputFormat.class);

        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(Text.class);

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

このコードは、カスタムの JoinMapperJoinReducer を持つ MapReduce ジョブを定義しています。マッパーは dinosaurs.txtlocations.txt から入力データを読み取り、恐竜の名前をキーとして、データ型("DIN" または "LOC")と対応する値を含むキーバリューペアを出力します。その後、リデューサはキーで値をグループ化し、恐竜の情報と場所を結合することで結合操作を行います。

コードをコンパイルするには、以下のコマンドを実行します。

mkdir classes
javac -source 8 -target 8 -cp "/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 classes JoinDinosaurs.java
jar -cvf join-dinosaurs.jar -C classes/.

次に、以下のコマンドを使用して MapReduce ジョブを実行します。

hadoop jar join-dinosaurs.jar JoinDinosaurs /home/hadoop/join-lab /home/hadoop/join-lab/output

このコマンドは、join-dinosaurs.jar ファイルから JoinDinosaurs クラスを実行し、入力ディレクトリ /home/hadoop/join-labdinosaurs.txtlocations.txt が含まれています)と出力ディレクトリ /home/hadoop/join-lab/output を指定します。

ジョブが正常に完了した後、/home/hadoop/join-lab/output ディレクトリに出力を表示できます。

出力を分析する

このステップでは、結合操作の出力を分析して、恐竜の世界に関する洞察を得ます。

まず、出力ディレクトリの内容を確認しましょう。

hadoop fs -ls /home/hadoop/join-lab/output
hadoop fs -cat /home/hadoop/join-lab/output/part-r-00000

以下に似た出力が表示されるはずです。

brachiosaurus    Brachiosaurus,herbivore    Africa
stegosaurus      Stegosaurus,herbivore      North America
trex     Tyrannosaurus Rex,carnivore        North America
velociraptor     Velociraptor,carnivore     Asia

この出力は、結合されたデータを示しており、各行には恐竜の名前、その詳細(種類と食性)、およびその化石が見つかった場所が含まれています。

出力を基に、以下のような観察ができます。

  • 「ティラノサウルス・レックス」(T-Rex)と「ベロシラプトル」は肉食性の恐竜であり、「ブラキオサウルス」と「ステゴサウルス」は草食性でした。
  • 「ブラキオサウルス」の化石はアフリカで見つかり、「ステゴサウルス」と「ティラノサウルス・レックス」の化石は北アメリカで見つかり、「ベロシラプトル」の化石はアジアで見つかりました。

これらの洞察は、古生物学者が異なる地質学的地域にわたるさまざまな恐竜種の分布、行動、進化をよりよく理解するのに役立ちます。

まとめ

この実験では、Hadoop MapReduce を使った結合操作の実装を検討しました。複数のソースからのデータを組み合わせることで、恐竜の世界、その種類、食性、化石の場所などに関する貴重な洞察を得ることができました。

この実験では、MapReduce を使ってデータを結合する概念を紹介しました。マッパーは結合操作のためのデータを準備し、リデューサはキーで値をグループ化し、情報を結合することで実際の結合を行います。

環境のセットアップ、データの準備、MapReduce ジョブの実装、出力の分析という実践的な経験を通じて、Hadoop の強力なデータ処理機能を活用して複雑な分析問題を解決する方法に関する実践的な知識を得ました。

この実験は、結合操作の理解を深めるだけでなく、Hadoop MapReduce の使用、Java コードの記述、Linux 環境でのコマンドの実行に関するスキルを強化しました。ゼロから完全なソリューションを設計して実装する経験は非常に貴重であり、データエンジニアまたはデータサイエンティストとしての成長に確実に貢献するでしょう。