BigData/Reports/实验二实验报告.md
2024-07-06 22:01:54 +08:00

5.8 KiB
Raw Permalink Blame History

大数据实验二实验报告

任昌骏 2021211180

实验描述

在实验中使用IDEA构建大数据工程通过Java编写程序并通过集群运行完成单词计数的任务。首先在本地上完成WordCount工程的创建和程序的编写;然后将程序打包之后上传到之前搭建的hadoop集群中运行。

实验目的

  1. 了解如何使用IDEA构建大数据工程
  2. 熟悉使用Java语言编写大数据程序
  3. 了解MapReduce的工程原理
  4. 掌握如何在集群上运行hadoop程序

实验环境

Hadoop环境为使用Docker搭建的Hadoop 2.7.7环境,基础系统镜像为archlinux。使用hdfs dfsadmin -report确保集群运行正确。

image-20240515162247831

使用的JDK版本为1.8.0_412IDEA版本为2024.1.1。

实验步骤

创建工程并编写代码

IDEA中创建Maven工程,添加相关的依赖并创建log4j.xml配置文件。创建本次实验中的主类WordCount,并编写对应的逻辑代码。

package top.rrricardo;

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;

import java.io.IOException;
import java.util.StringTokenizer;

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

        public void map(Object key, Text value, Context context) throws IOException, InterruptedException {
            StringTokenizer tokenizer = new StringTokenizer(value.toString());

            while (tokenizer.hasMoreTokens()) {
                word.set(tokenizer.nextToken());
                context.write(word, one);
            }
        }
    }

    public static class IntSumReducer extends Reducer<Text, IntWritable, Text, IntWritable> {
        private final IntWritable result = new IntWritable();

        public void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
            int sum = 0;
            for (IntWritable value : values) {
                sum += value.get();
            }

            result.set(sum);
            context.write(key, result);
        }
    }

    public static void main(String[] args) throws IOException, InterruptedException, ClassNotFoundException {
        Configuration configuration = new Configuration();
        String[] otherArgs = new GenericOptionsParser(configuration, args).getRemainingArgs();
        if (otherArgs.length != 2) {
            System.err.println("Usage: WordCount <in> <out>");
            System.exit(-1);
        }

        Job job = new Job(configuration, "Word Counter");
        job.setJarByClass(WordCount.class);
        job.setMapperClass(TokenizerMapper.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);
    }
}

上述的代码实际上由三个类构成,即WordCount主类和它的两个内部类TokenizeMapperIntSumReducer。单词技术的主要逻辑就位于两个内部类中,这两个内部类分别集成了MapperReducer,这对应着MapReduce框架中的两个核心工程,将任务分成若干个小任务,再将这一系列小任务的执行结果合并为最终结果。在这里,Map即为将字符串中的各个单词识别出来并将该单词的技术,而Reducer则负责收集这些结果,最终得到整个文本中的单词技术。主类这里负责解析用户的输出并启动对应的工作。

打包并上传到集群中

首先在IDEA中按照实验指导书中的步骤添加新的工件Artifacts

image-20240515163730035

然后运行打包指令打包成实际的JAR包。

image-20240515163818616

使用docker cp将打包好的JAR包上传到集群中。

image-20240515163903962

同时在上传一个文本文档作为下一步执行单词计数任务的输入,这里直接使用我们工程的源代码文件WordCount.java

image-20240515164013153

执行单词计数的任务

进入集群的主节点中,因为MapReduce的输入和输出文件都需要在hdfs文件系统中,因此首先使用指令将输入的文本文件上传到hdfs文件系统中。

首先创建一个lab2的文件夹作为区分:

image-20240515164259679

然后将我们输入的文本文件上传到该文件夹下:

image-20240515164356891

运行单词技术的程序,其中任务的输入文件为/lab2/WordCount.java,任务的输出文件夹为/lab2/output/

image-20240515164558443

使用命令检查任务运行的结果:

image-20240515164651664

说明任务运行的非常成功。