MapReduce学习之WordCount案例

14 篇文章 0 订阅
3 篇文章 0 订阅

在这里插入图片描述
maven:

 <dependencies>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-common</artifactId>
            <version>2.10.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-client</artifactId>
            <version>2.10.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-hdfs</artifactId>
            <version>2.10.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-mapreduce-client-core</artifactId>
            <version>2.10.1</version>
        </dependency>

代码:
WordCountMapper类代码

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

import java.io.IOException;

/**
 * @ProjectName: HadoopTest
 * @Package: PACKAGE_NAME
 * @ClassName: WordCountMapper
 * @Author: 82042
 * @Description:
 * @Date: 2020/11/15 21:48
 * @Version: 1.0
 */
/*
* 4个泛型
* KEYIN:k1的类型,这里是偏移量
* VALUEIN:v1的类型,文本数据
* KEYOUT:k2的类型  每个单词
* VALUEOUT:v2的类型 固定的数字
* MapReduce它定义了自定义的类型,就是为了方便序列化,只是把Long和String进行了封装
* */
public class WordCountMapper extends Mapper<LongWritable, Text,Text,LongWritable> {
    //继承map方法:将k1 v1转成k2 v2
    /*
    * 参数
    * key:k1
    * value:v1 每一行的文本数据
    * context:上下文对象,把各个流程串接到一起
    * */
    /*
    * 如何将k1 v1转为k2 v2?
    * 研究样例
    * k1    v1
    * 0     hello,world,hadoop
    * 15    hdfs,hive,hello
    * ---------------------
    * k2        v2
    * hello     1
    * world     1
    * hdfs      1
    * hadoop    1
    * hello     1
    * */
    @Override
    protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
        //这两个对象用来放字符串,和int
        Text text = new Text();
        LongWritable longWritable = new LongWritable();
        //1、将一行的文本数据进行拆分
            //由于text不能调用split,要用toString转换成字符串,因为测试数据用,分割
        String[] split = value.toString().split(",");
        //2、遍历数组,组装k2 v2
        for (String word : split) {
            //要转换成对应的类型才能写进去
            //context.write(new Text(word),new LongWritable(1));这行代码效率不太好,向上提取
            text.set(word);
            longWritable.set(1);
            context.write(text,longWritable);
        }
        //3、将k2和v2写入上下文
    }//map结束
}


Reducer代码

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

import java.io.IOException;

/**
 * @ProjectName: HadoopTest
 * @Package: PACKAGE_NAME
 * @ClassName: WordCountReducer
 * @Author: 82042
 * @Description:
 * @Date: 2020/11/15 22:12
 * @Version: 1.0
 */
/*
* 4个泛型
* KEYIN:k2类型
* VALUEIN:v2类型
* KEYOUT:k3类型
* VALUEOUT:v3类型
*
* */
public class WordCountReducer extends Reducer<Text, LongWritable,Text,LongWritable> {
    //将新的k2、v2转成k3、v3
    /*
    * 参数:
    * key:新k2
    * values:集合 新v2
    * context:上下文对象
    * ------------------
    * 如何将的k2,v2转化为k3,v3
    * k2        v2
    * hello     <1,1,1>
    * world     <1,1>
    * hadoop    <1>
    * ----------------
    * k3        v3
    * hello     3
    * world     2
    * hadoop    1
    * 发现只要遍历将每个单词集合中的1相加即可
    * */
    @Override
    protected void reduce(Text key, Iterable<LongWritable> values, Context context) throws IOException, InterruptedException {
        long count=0;
        //1、遍历集合,将集合中的数字相加,得到k3
        for (LongWritable value : values) {
            count +=value.get();//get方法返回long
        }
        //2、将k3和v3写入上下文中
        context.write(key,new LongWritable(count));
    }
}

JobMain代码

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.conf.Configured;
import org.apache.hadoop.fs.FileSystem;
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.TextInputFormat;
import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;
import org.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner;

import java.net.URI;

/**
 * @ProjectName: HadoopTest
 * @Package: PACKAGE_NAME
 * @ClassName: JobMain
 * @Author: 82042
 * @Description:
 * @Date: 2020/11/16 16:52
 * @Version: 1.0
 */
//主类要继承Configured并且实现Tool
public class JobMain extends Configured implements Tool {
    //该方法用于指定一个job任务
    @Override
    public int run(String[] strings) throws Exception {
        //1、创建一个job任务对象,super.getConf获取从main方法中放入的Configuration对象
        Job job = Job.getInstance(super.getConf(), "wordCount");
        //如果打包运行出错,则需要加该配置
        job.setJarByClass(JobMain.class);
        //2、配置job任务对象,8个步骤
        //第一步:指定文件的读取方式和读取路径
        job.setInputFormatClass(TextInputFormat.class);
        //hdfs目录
        TextInputFormat.addInputPath(job,new Path("hdfs://node01:8020/wordcount"));
        //本地目录
//        TextInputFormat.addInputPath(job, new Path("file:///D:\\Mapreduce\\input.txt"));
        //第二步:map阶段的处理方式
        job.setMapperClass(WordCountMapper.class);
        //设置map阶段k2的类型
        job.setMapOutputKeyClass(Text.class);
        //设置v2的类型
        job.setMapOutputValueClass(LongWritable.class);
        //第三、四、五、六采用默认的方式
        //第七步:指定Reduce的处理方式
        job.setReducerClass(WordCountReducer.class);
        //设置k3
        job.setOutputKeyClass(Text.class);
        //设置v3
        job.setOutputValueClass(LongWritable.class);
        //第八步:设置输出类型
        job.setOutputFormatClass(TextOutputFormat.class);
        //设置一个输出的路径,这里不存在的路径会自动创建,这个目录不能已经存在
        //提取出Path,便于之后output已经存在就删除的代码
        Path path = new Path("hdfs://node01:8020/wordcount_out");
        //hdfs目录
        TextOutputFormat.setOutputPath(job,path);
        //本地目录
//        TextOutputFormat.setOutputPath(job,new Path("file:///D:\\MapReduce\\output"));
        //判断output存在与否
        FileSystem fileSystem = FileSystem.get(new URI("hdfs://node01:8020"), new Configuration());
        boolean exists = fileSystem.exists(path);
        //存在则删除
        if (exists)fileSystem.delete(path,true);//true是递归删除
        //等待任务结束,返回的是任务的成功还是失败
        boolean b = job.waitForCompletion(true);
        //这个返回值最终给了main方法中调用run的地方
        return b? 0:1;
    }
    //入口方法
    public static void main(String[] args) throws Exception {
        Configuration configuration = new Configuration();
        //启动job任务,其中的Tool参数可以直接newJobMain,这个run方法就是上面的run方法
        //返回值是任务是否成功,0成功否则失败
        //这个传进去的Configuration是放到Configured中,但JobMain继承了所以用super.getConf可以得到
        int run = ToolRunner.run(configuration, new JobMain(), args);
        System.exit(run);
    }
}

代码测试
在这里插入图片描述

hadoop jar mapReduceCode-1.0-SNAPSHOT.jar(jar包名) JobMain()

二、本地运行模式
将数据的输入和输出都放在本地,就能够以单进程的形式运行了

改一下输入和输出就行
     //hdfs目录
//        TextInputFormat.addInputPath(job,new Path("hdfs://node01:8020/wordcount"));
        //本地目录
        TextInputFormat.addInputPath(job, new Path("file:///D:\\Mapreduce\\input.txt"));
。
。
。
//设置一个输出的路径,这里不存在的路径会自动创建,这个目录不能已经存在
        //hdfs目录
//        TextOutputFormat.setOutputPath(job,new Path("hdfs://node01:8020/wordcount_out"));
        //本地目录
        TextOutputFormat.setOutputPath(job,new Path("file:///D:\\MapReduce\\output"));

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值