mapreduce统计单词词频

经典案例:mapreduce统计单词词频

前置准备

①hadoop集群
②idea
③Xshell

1. 首先在Windows上打开编程工具idea,建立maven工程(此步骤较为简单,不做详细介绍)。

2. 在建立的工程下找到并打开pom.xml,将以下代码粘贴进去,粘贴完成后导入依赖

    <dependencies>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-common</artifactId>
            <version>2.7.7</version>
        </dependency>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-hdfs</artifactId>
            <version>2.7.7</version>
        </dependency>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-client</artifactId>
            <version>2.7.7</version>
        </dependency>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-mapreduce-client-core</artifactId>
            <version>2.7.7</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <version>2.4</version>
                <configuration>
                    <archive>
                        <manifest>
                            <addClasspath>true</addClasspath>
                            <classpathPrefix>lib/</classpathPrefix>
                            <mainClass></mainClass>
                        </manifest>
                    </archive>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.0</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
        </plugins>
    </build>

3.在java下建立cn.itcast.example.mr包,在包下建立如下图所示的三个类

在这里插入图片描述

4.在WordCountMapper类中编写如下map阶段的代码

package cn.itcast.example.mr;

import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;

import java.io.IOException;

/*
Mapper<KEYIN,VALUEIN,KEYOUT,VALUEOUT>

KEYIN:表示mapper阶段数据输入的时候key的数据类型,在默认的读取数据组件下,叫InputFormat,它的行为是一行一行地读取待处理的数据
      读取一行,返回一行给我们的mr程序,在这种情况下 keyin 就表示每一行的起始偏移量,因此数据偏移量是Long

VALUEIN:表示mapper阶段数据输入的时候value的数据类型,在默认的读取数据组件下 valuein 就表示读取的这一行内容,因此数据类型是String

KEYOUT:表示mapper阶段数据输出的时候key的数据类型,在本案例中,输出的key是单词,因此数据类型是String

VALUEOUT:表示mapper数据输出的时候value的数据类型,在本案例中,输出的key是单词的次数,因此数据类型是Integer

这里所说的数据类型String Long都是jdk自带的类型,在序列化的时候效率低下,因此hadoop自己封装了一套数据类型
long---->LongWritable
String---->Text
Integer---->Intwritable
null---->NullWritable
 */
public class WordCountMapper extends Mapper<LongWritable, Text,Text, IntWritable> {
    /*
    这里就是mapper阶段具体的业务逻辑实现方法,该方法的调用取决于读取数据的组件有没有给mr传入数据
    如果有,每传入一个<k,v>对,该方法就会被调用一次
     */
    protected void map(LongWritable key,Text value,Context context) throws IOException,InterruptedException{
//        拿到传入进来的一行内容,把数据类型转化为String
        String line = value.toString();

//        将这一行内容按照分隔符进行切割,切割成一个单词数组
        String words[] = line.split(" ");

//        遍历数组,每出现一个单词,就标记数字1
        for (String word : words){
//            使用mr程序的上下文context,把mapper阶段处理的数据发送出去
//            作为reduce阶段的输入数据
            context.write(new Text(word),new IntWritable(1));
        }
    }
}

5.在WordCountReducer类中编写reduce阶段的代码

package cn.itcast.example.mr;

import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;

import java.io.IOException;

/*
KEYIN:就是reducer阶段输入的数据key类型,对应mapper阶段的输出key类型,在本案例中就是单词Text
VALUEIN:就是reducer阶段输入的数据value类型,对应mapper阶段的输出value类型,在本案例中就是单词次数 IntWritable
KEYOUT:就是reducer阶段输出的数据key类型,在本案例中就是单词Text
VALUEOUT:就是reducer阶段输出的数据value类型,在本案例中就是单词总次数IntWritable
 */
public class WordCountReducer extends Reducer<Text, IntWritable,Text,IntWritable> {
/*
按照key是否相同作为一组去调用reduce方法
本方法的key就是这一组相同kv对的共同key
把这一组所有的v作为一个迭代器传入我们的reduce方法
 */

    @Override
    protected void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
//        定义一个计数器
        int count = 0;

//        遍历一组迭代器,把每一个数量1累加起来就构成了单词的总次数
        for (IntWritable value:values) {
            count += value.get();
        }

//        把最终的结果输出
        context.write(key,new IntWritable(count));
    }
}

6.在WordCountDriver中编写主类的代码

package cn.itcast.example.mr;


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;

/*
这个类就是mr程序运行时候的主类,本类中组装了一些程序运行时所需要的信息
比如:使用的是哪个mapper类,哪个reducer类,输入数据在哪,输出数据在哪
 */
public class WordCountDriver {
    public static void main(String[] args)throws Exception{
//        通过Job来封装本次mr的相关信息
        Configuration conf = new Configuration();
        Job job = Job.getInstance(conf);

//        指定本次mr job jar包运行主类
        job.setJarByClass(WordCountDriver.class);

//        指定本次mr,所用的mapper,reducer类分别是什么
        job.setMapperClass(WordCountMapper.class);
        job.setReducerClass(WordCountReducer.class);

//        指定本次mr,mapper阶段的输出k,v类型
        job.setMapOutputKeyClass(Text.class);
        job.setMapOutputValueClass(IntWritable.class);

//        指定本次mr最终输出的k,v类型
        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(IntWritable.class);

//        指定本次mr输入的数据路径和最终输出结果存放在什么位置
        FileInputFormat.setInputPaths(job,"/wordcount/input");
        FileOutputFormat.setOutputPath(job,new Path("/wordcount/output"));

//        job.submit();
//        提交程序,并且监控打印程序执行情况
        boolean b = job.waitForCompletion(true);
        System.exit(b?0:1);
    }
}

7.将编写好的代码打成jar包

7.1 复制主类的路径

在这里插入图片描述

7.2 将复制的路径粘贴到pom.xml的如下位置

在这里插入图片描述
在这里插入图片描述

7.3 打成jar包

点击右上角的Maven,出现右边对话框,双击package,稍作等待
在这里插入图片描述
之后会在左边出现如下target包,箭头所指即为jar包
在这里插入图片描述

8.运行jar包

8.1 上传jar包

打开VMware,并用Xshell连接,启动hadoop集群,将刚才打包的example-mr-1.0.jar包拖入Xshell,并查看(如图所示)
在这里插入图片描述

8.2 创建数据

在xk用户下分别创建 1.txt 和 2.txt ,写入如下数据(因为我没有数据,所以就自己构造了)

#单词之间以空格分隔
[xk@hadoop01 ~]$ vi 1.txt
hadoop spark hello hello
spark kylin flume
flume kylin

[xk@hadoop01 ~]$ vi 2.txt
hadoop spark kylin hello sqoop
spark hadoop hadoop sqoop

8.3 在hdfs上创建如下文件夹

[xk@hadoop01 ~]$ hadoop fs -mkdir -p /wordcount/input

8.4 将1.txt和2.txt上传到/wordcount/input

[xk@hadoop01 ~]$ hadoop fs -put 1.txt 2.txt /wordcount/input

8.5 运行jar

[xk@hadoop01 ~]$ hadoop jar example-mr-1.0.jar 

9.查看运行结果

[xk@hadoop01 ~]$ hadoop fs -ls /wordcount
Found 2 items
drwxr-xr-x   - xk supergroup          0 2020-06-27 17:46 /wordcount/input
drwxr-xr-x   - xk supergroup          0 2020-06-27 17:48 /wordcount/output
[xk@hadoop01 ~]$ hadoop fs -ls /wordcount/output
Found 2 items
-rw-r--r--   3 xk supergroup          0 2020-06-27 17:48 /wordcount/output/_SUCCESS
-rw-r--r--   3 xk supergroup         49 2020-06-27 17:48 /wordcount/output/part-r-00000
[xk@hadoop01 ~]$ hadoop fs -cat /wordcount/output/part-r-00000
flume	2
hadoop	4
hello	3
kylin	3
spark	4
sqoop	2
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小刘新鲜事儿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值