沙漠数据探索之旅

HadoopHadoopBeginner
立即练习

💡 本教程由 AI 辅助翻译自英文原版。如需查看原文,您可以 切换至英文原版

引言

在一片广袤的沙漠荒原中,一位孤独的商人踏上了一段充满危险的旅程,试图揭开隐藏在炙热沙层下的秘密。商人的目标是发现古代遗物和文物,解开一个早已被遗忘的文明的秘密。然而,沙漠中埋藏的海量数据构成了巨大的挑战,需要借助 Hadoop MapReduce 的力量来有效地处理和分析这些信息。


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/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-288986{{"`沙漠数据探索之旅`"}} hadoop/mappers_reducers -.-> lab-288986{{"`沙漠数据探索之旅`"}} hadoop/yarn_jar -.-> lab-288986{{"`沙漠数据探索之旅`"}} hadoop/process -.-> lab-288986{{"`沙漠数据探索之旅`"}} hadoop/aggregating -.-> lab-288986{{"`沙漠数据探索之旅`"}} hadoop/udf -.-> lab-288986{{"`沙漠数据探索之旅`"}} end

实现 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

在这一步骤中,我们将创建一个 Reducer 类来聚合 Mapper 发出的数据。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 对象,表示单词,输入值是一个 LongWritable 对象的 Iterable,表示由 Mappers 发出的该单词的计数。
  2. reduce 方法遍历这些值,并计算给定单词的所有计数的总和。
  3. reduce 方法随后使用 context.write 发出单词作为键,并将总计数作为值。

创建 Driver

在这一步骤中,我们将创建一个 Driver 类来协调 MapReduce 作业。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 退出。

编译并运行作业

在这一步骤中,我们将编译 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 参数用于指定 Java 源代码和目标字节码版本,以匹配 Hadoop 中的 Java 版本。

接下来,使用 jar 命令打包 class 文件:

jar -cvf Artifact.jar *.class

最后,我们可以运行 MapReduce 作业,所有关于沙漠的数据已经存储在 HDFS 的 /input 目录中:

hadoop jar Artifact.jar ArtifactDriver /input /output

执行命令后,你应该会看到指示 MapReduce 作业进度的日志。作业完成后,你可以在 HDFS 的 /output 目录中找到输出文件。并使用以下命令查看结果:

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

总结

恭喜你!你已经成功探索了为 Hadoop MapReduce 作业编写 Mapper 和 Reducer 的过程。在一个涉及沙漠商人寻找古代遗迹的场景中,你利用 Hadoop MapReduce 的强大功能分析了大量的沙漠数据。通过实现 ArtifactMapper 类提取了相关数据,而 ArtifactReducer 类则聚合了 Mapper 的输出。通过 ArtifactDriver 类协调整个过程,进一步巩固了你的理解。在整个过程中,我们强调了最佳实践、完整的代码示例和验证检查。这种实践经验加深了你对 Hadoop MapReduce 的理解,并突出了有效的学习体验设计。

您可能感兴趣的其他 Hadoop 教程