Hadoop(三)MapReducer本地模式下的WordCount编程实例(一看就会)

写在前面
这篇博客我们一块看一下 本地模式 下,怎样用mapreduce记录一个大文件的单词个数的。

创建maven工程

请参考博主hdfs博客,过两天更。

导入依赖

在pom.xml添加如下代码

<dependencies>
        <!--添加日志需要的包依赖-->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-slf4j-impl</artifactId>
            <version>2.12.0</version>
        </dependency>
         <!--hadoop的依赖包-->
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-client</artifactId>
            <version>3.1.3</version>
        </dependency>
    </dependencies>

创建配置文件

在项目的src/main/resources目录下,新建一个文件,命名为“log4j2.xml”,在文件中填入如下数据:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="error" strict="true" name="XMLConfig">
    <Appenders>
        <!-- 类型名为Console,名称为必须属性 -->
        <Appender type="Console" name="STDOUT">
            <!-- 布局为PatternLayout的方式,
            输出样式为[INFO] [2018-01-22 17:34:01][org.test.Console]I'm here -->
            <Layout type="PatternLayout"
                    pattern="[%p] [%d{yyyy-MM-dd HH:mm:ss}][%c{10}]%m%n" />
        </Appender>

    </Appenders>

    <Loggers>
        <!-- 可加性为false -->
        <Logger name="test" level="info" additivity="false">
            <AppenderRef ref="STDOUT" />
        </Logger>

        <!-- root loggerConfig设置 -->
        <Root level="info">
            <AppenderRef ref="STDOUT" />
        </Root>
    </Loggers>
</Configuration>

创建包名

创建包名com.yuaf.wordcount

创建Mapper类

package com.yuaf.wordcount;

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;

public class WordCountMapper extends Mapper<LongWritable, Text, Text, IntWritable> {
    
    
    Text outK = new Text();
    IntWritable outV = new IntWritable(1);

    @Override
    //这个map的意思是,你传过来的数据我以空格分隔,但后把一个个单词计数为一输出
    protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
    
    
       //获取一行且分割
        String[] split = value.toString().split(" ");
	   //封装且输出
        for (String sp : split) {
    
    
            outK.set(sp);
            context.write(outK, outV);
        }
    }
}


创建Reducer类

package com.yuaf.wordcount;

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

import java.io.IOException;

public class WordCountReducer extends Reducer<Text, IntWritable, Text, IntWritable> {
    
    
    IntWritable outV = new IntWritable();
	int sum;
    @Override
    //这个reduce的作用是算出每个key出现了多少次,且将结果输出
    protected void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
    
    
        sum = 0;
        for (IntWritable value : values) {
    
    
            sum += value.get();
        }
        outV.set(sum);
        context.write(key, outV);
    }
}

创建Driver主函数

package com.yuaf.wordcount;

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 java.io.IOException;


public class WordCountDriver {
    
    
    public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
    
    
        //1.获取配置信息,创建job对象
        Job job = Job.getInstance(new Configuration());
        //2.关联自己写的Mapper
        job.setMapperClass(WordCountMapper.class);
        //3.关联自己写的Reducer
        job.setReducerClass(WordCountReducer.class);
        //4.设置Mapper的输出格式
        job.setMapOutputKeyClass(Text.class);
        job.setMapOutputValueClass(IntWritable.class);
        //5.设置文档最终的输出格式
        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(IntWritable.class);
        //6.设置输入输出路径
        FileInputFormat.setInputPaths(job, new Path("E:/input/word.txt"));
        FileOutputFormat.setOutputPath(job, new Path("E:/output"));
        //7.提交job
        boolean b = job.waitForCompletion(true);
        System.exit(b ? 0 : 1);
    }
}

准备数据

Driver主函数中我们设置了文件的输入输出路径,其中输入路径存放需要计数的文档,输出路径需要是一个不存在的文件夹
我们来看一下文件
在这里插入图片描述

启动Driver主程序

在这里插入图片描述结果返回0,说明程序运行成功,让我们一块来看一下结果。

在这里插入图片描述查看这个文件
在这里插入图片描述
可以看到第一行是一个空格,是因为我们输入数据时,第一个love前有一个空格。

猜你喜欢

转载自blog.csdn.net/Kruskual/article/details/108487446