Фьюзинг данных о динозаврах с использованием Hadoop

HadoopHadoopBeginner
Практиковаться сейчас

💡 Этот учебник переведен с английского с помощью ИИ. Чтобы просмотреть оригинал, вы можете перейти на английский оригинал

Введение

В эпоху динозавров бесстрашний охотник за динозаврами по имени Алекс отправляется в захватывающую миссию, чтобы раскрыть секреты этих доисторических существ. Цель Алексе — собрать ценные данные из различных источников и провести глубокий анализ, чтобы получить представление о поведении, питании и эволюции разных видов динозавров.

Для этого Алексе необходимо использовать силу 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

Далее, создадим два файла данных: dinosaurs.txt и locations.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 - lab в hdfs с помощью следующей команды:

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

Реализация операции соединения

В этом шаге мы реализуем задачу MapReduce для выполнения операции соединения между файлами dinosaurs.txt и locations.txt.

Создайте новый Java-файл с именем JoinDinosaurs.java в директории /home/hadoop/join-lab с таким содержанием:

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);
    }
}

В этом коде определяется задача MapReduce с пользовательскими классами JoinMapper и JoinReducer. Mapper читает входные данные из dinosaurs.txt и locations.txt и выдает пары ключ-значение с именем динозавра в качестве ключа и типом данных ("DIN" или "LOC") вместе с соответствующим значением. Затем Reducer выполняет операцию соединения, группируя значения по ключу и объединяя информацию о динозаврах с информацией о месте обитания.

Для компиляции кода выполните следующую команду:

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

Эта команда запускает класс JoinDinosaurs из файла join-dinosaurs.jar, с входной директорией /home/hadoop/join-lab (содержащей dinosaurs.txt и locations.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

Данный результат показывает объединенные данные, где каждая строка содержит имя динозавра, его характеристики (вид и питание) и место, где были найдены его ископаемые.

Основываясь на результате, мы можем сделать следующие наблюдения:

  • Tyrannosaurus Rex (T - Rex) и Velociraptor были плотоядными динозаврами, в то время как Brachiosaurus и Stegosaurus были травоядными.
  • Ископаемые Brachiosaurus были найдены в Африке, ископаемые Stegosaurus и Tyrannosaurus Rex были найдены в Северной Америке, а ископаемые Velociraptor были найдены в Азии.

Эти выводы могут помочь палеонтологам лучше понять распределение, поведение и эволюцию разных видов динозавров по различным геологическим регионам.

Резюме

В этом лабораторном занятии мы изучили реализацию операции соединения с использованием Hadoop MapReduce. Объединяя данные из нескольких источников, мы смогли получить ценные знания о мире динозавров, включая их виды, питание и места обитания ископаемых.

В лабораторной работе была представлена концепция соединения данных с использованием MapReduce, где mapper подготавливает данные для операции соединения, а reducer выполняет фактическое соединение, группируя значения по ключу и объединяя информацию.

С помощью практического опыта настройки среды, подготовки данных, реализации задачи MapReduce и анализа результата мы приобрели практические знания о том, как использовать мощные возможности обработки данных Hadoop для решения сложных аналитических задач.

Эта лабораторная работа не только усилила наше понимание операций соединения, но и укрепило наши навыки работы с Hadoop MapReduce, написания Java - кода и выполнения команд в среде Linux. Опыт проектирования и реализации полного решения с нуля был бесценен и, несомненно, способствовал нашему развитию в качестве инженеров по обработке данных или специалистов по данным.