Hadoop——MapReduce实现单词统计和排序(图文超详细版)(内含遇到错误的解决方法)

一、前情提要

上一篇文章介绍了MapReduce的Api调用方法以及eclipse的配置,这次我们就利用MapReduce对英语文章文件进行单词统计!

有需要的欢迎看看我的前一篇文章:MapReduce相关eclipse配置及Api调用

二、前置条件

需要安装 下载方法
IDEA 自备
hadoop-eclipse-plugin-2.7.0.jar 百度网盘下载 , 提取码:f259
MobaXterm 百度网盘下载,提取码:f64v

确保Hadoop集群搭建成功,若还没搭建成功,欢迎看看我之前的文章:Hadoop集群搭建(步骤图文超详细版)

本次将会用到的,HDFS命令大全:Hadoop——HDF的Shell命令,建议大家在操作时看看!!

三、创建Maven工程

打开IDEA工具,在左上角点击 “File”——“New”——“Project” ↓
在这里插入图片描述
选择 Maven 项目↓
在这里插入图片描述
填写项目信息↓
在这里插入图片描述
创建项目成功之后,我们打开pom.xml↓
在这里插入图片描述
在配置文件中,增加 Hadoop 的相关依赖↓
在这里插入图片描述
代码如下↓
注意:< version >< /version >中替换你 Hadoop 的版本号,我这里是2.7.3!

<dependencies>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-client</artifactId>
            <version>2.7.3</version>
        </dependency>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-hdfs</artifactId>
            <version>2.7.3</version>
        </dependency>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-common</artifactId>
            <version>2.7.3</version>
        </dependency>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-annotations</artifactId>
            <version>2.7.3</version>
        </dependency>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-auth</artifactId>
            <version>2.7.3</version>
        </dependency>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-yarn-api</artifactId>
            <version>2.7.3</version>
        </dependency>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-yarn-common</artifactId>
            <version>2.7.3</version>
        </dependency>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-mapreduce-client-core</artifactId>
            <version>2.7.3</version>
        </dependency>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-mapreduce-client-common</artifactId>
            <version>2.7.3</version>
        </dependency>
    </dependencies>

点击右上角的这个按钮,重新加载依赖库和配置文件↓
在这里插入图片描述

四、修改Windows系统变量

右键桌面上的 “此电脑” 图标,点击 “属性” ,在环境变量中新建系统变量↓
在这里插入图片描述
系统变量中添加hadoop文件路径↓
在这里插入图片描述

五、编写MapReduce的jar包程序

上一篇文章中,我们把 hadoop 整个文件从 linux 系统上压缩并解压至 Windows 上,现在我们打开这个 hadoop 文件,来到 /etc/hadoop/ 这个目录下,将以下四个文件拷贝复制到 IDEA 刚创建的项目中
四个文件↓
在这里插入图片描述
复制到项目的 resources 文件夹下↓
在这里插入图片描述

紧接着我们创建一个包和三个类:WordMain.javaWordMapper.javaWordReduce.java

在这里我先来解释一下这三个包分别的用处↓

WordMain类是对任务的创建进行部分配置,主要是在Job中设定相应的Mapper类和Reduce类,这样任务在运行时才知道使用相应类进行处理;WordMain驱动类还可以对 MapReduce程序进行相应配置,让任务在haadoop集群运行所定义的配置中进行。

WordMapper类继承了Mapper方法,作用是将单词从大写到小写a到z的规律进行排序

WordReduce类则是继承了Reducer方法,作用是将单词利用正则表达式进行拆分统计

在这里插入图片描述
WordMain驱动类代码↓

package com.mapreducetest;

import java.util.Date;
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.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.util.GenericOptionsParser;

public class WordMain {
    public static void main(String[] args) throws Exception {
        // Configuration类:读取Hadoop的配置文件,如 site-core.xml...;
        // 也可用set方法重新设置(会覆盖):conf.set("fs.default.name", "hdfs://xxxx:9000")
        Configuration conf = new Configuration();
        // 将命令行中参数自动设置到变量conf中
        String[] otherArgs = new GenericOptionsParser(conf, args).getRemainingArgs();

        /**
         * 这里必须有输入输出
         */

        if (otherArgs.length != 2) {
            System.err.println("Usage: wordcount <in> <out>");
            System.exit(2);
        }

        Job job = new Job(conf, "word count"); // 新建一个 job,传入配置信息
        job.setJarByClass(WordMain.class); // 设置 job 的主类
        job.setMapperClass(WordMapper.class); // 设置 job 的 Mapper 类
        job.setCombinerClass(WordReduce.class); // 设置 job 的 作业合成类
        job.setReducerClass(WordReduce.class); // 设置 job 的 Reducer 类
        job.setOutputKeyClass(Text.class); // 设置 job 输出数据的关键类
        job.setOutputValueClass(IntWritable.class); // 设置 job 输出值类
        FileInputFormat.addInputPath(job, new Path(otherArgs[0])); // 文件输入
        FileOutputFormat.setOutputPath(job, new Path(otherArgs[1])); // 文件输出
        boolean result = false;
        try {
            result = job.waitForCompletion(true);
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println(new Date().toGMTString() + (result ? "成功" : "失败"));
        System.exit(result ? 0 : 1); // 等待完成退出
    }
}

WordMapper类代码↓

package com.mapreducetest;

import java.io.IOException;
import java.util.Date;
import java.util.StringTokenizer;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;
// 创建一个 WordMap类 继承于 Mapper抽象类
public class WordMapper extends Mapper<Object, Text, Text, IntWritable> {
    private final static IntWritable one = new IntWritable(1);
    private Text word = new Text();

    // Mapper抽象类的核心方法,三个参数
    public void map(Object key, // 首字符偏移量
                    Text value, // 文件的一行内容
                    Context context) // Mapper端的上下文,与 OutputCollector 和 Reporter 的功能类似
            throws IOException, InterruptedException {
        String[] ars = value.toString().split("['.;,?| tnrf]");
        for (String tmp : ars) {
            if (tmp == null || tmp.length() <= 0) {
                continue;
            }
            word.set(tmp);
            System.out.println(new Date().toGMTString() + ":" + word + "出现一次,计数+1");
            context.write(word, one);
        }
    }
}

WordReducer类代码↓

package com.mapreducetest;

import java.io.IOException;
import java.util.Date;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;

// 创建一个 WordReduce类 继承于 Reducer抽象类
public class WordReduce extends Reducer<Text, IntWritable, Text, IntWritable>
{
    private IntWritable result = new IntWritable(); // 用于记录 key 的最终的词频数

    // Reducer抽象类的核心方法,三个参数
    public void reduce(Text key, // Map端 输出的 key 值
                       Iterable<IntWritable> values, // Map端 输出的 Value 集合(相同key的集合)
                       Context context) // Reduce 端的上下文,与 OutputCollector 和 Reporter 的功能类似
            throws IOException, InterruptedException
    {
        int sum = 0;
        for (IntWritable val : values) // 遍历 values集合,并把值相加
        {
            sum += val.get();
        }
        result.set(sum); // 得到最终词频数
        System.out.println(new Date().toGMTString()+":"+key+"出现了"+result);
        context.write(key, result); // 写入结果
    }
}

三个文件都弄好后,在IDEA最右侧有一栏 Maven工具栏,打开它后在 Lifecycle 找到 “clean” 和 “package” 两个指令,先双击 clean 待程序完后,再双击 package 进行打包!接着就能在项目的 target 文件中看到我们打包好的 jar 包文件
在这里插入图片描述

六、在Linux执行单词统计排序

我们来到 linux 的 hadoop 主节点中,将刚刚打包的jar包单词文本文件一同放 /home 目录下↓
在这里插入图片描述
启动hadoop集群,命令↓

start-all.sh

接着我们 HDFS 上创建一个 ainput 文件夹用于存放上传的文件,然后我们把单词文件上传HDFS↓
别忘了给文件夹赋予可修改可读取可执行的权限,命令↓

hdfs dfs -mkdir /ainput
hdfs dfs -put /home/wordstest.TXT /ainput
hdfs dfs -chmod 777 /ainput

在这里插入图片描述

重头戏来了!!我们利用上传的单词统计驱动jar包对单词文件进行单词统计,命令↓

hadoop jar MapReduceTest-1.0-SNAPSHOT.jar com.mapreducetest.WordMain /ainput /aoutput

在这里插入图片描述
解析命令↓

格式:hadoop jar [jar文件位置] [jar主类] [HDFS输入位置] [HDFS输出位置]

Tips:目前我就在jar所在目录,所以只需要填写jar包名称就好了,如果不在同目录下,记得加路径+jar包名

在这里插入图片描述
如何找到WordMain类路径↓
在这里插入图片描述
单词排序统计结果↓

Tips:其中part-r-00000文件保存的是运行结果,能看到文件中的单词已从大写到小写a到z的规律进行排序好了↓

在这里插入图片描述

六、在Eclipse执行单词统计排序

我们在Eclipse HDFS文件系统中,在 /user目录下新建一个文件夹 user,在 user 文件夹下,新建 wordinput 文件夹,上传 英文 文件↓
在这里插入图片描述
右键->Run As->Run Configurations->Arguments,在左边的导航列表点击Java Application选择WordMain Java程序↓在这里插入图片描述
设置运行参数↓
输入路径:hdfs://linux主机IP地址:9000/user/wordinput
输出路径:hdfs://linux主机IP地址:9000/user/wordoutput
然后点击运行↓
在这里插入图片描述
单词排序统计结果↓
在这里插入图片描述

Tips:如果运行后,终端报错:java.io.IOException: (null) entry in command string: null chmod 0700 E:tmphadoopmapredstagingte

解决方法:在C:WindowsSystem32 目录下添加hadoop.dll 文件即可,hadoop.dll文件github下载地址

结果分析:我们打开 part-r-00000 这个文件,里面保存的是统计排序后的运行结果,能看到文件中的单词已从大写到小写a到z的规律进行排序好了↓

在这里插入图片描述

本次分享到此结束,谢谢大家阅读!!

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
< <上一篇
下一篇>>