Hadoop05——WordCount的非MapReduce实现和MapReduce在Windows下实现

4 篇文章 0 订阅
2 篇文章 0 订阅

WordCount的非MapReduce实现和MapReduce在Windows下实现

非MapReduce实现

package SimpleTest;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

public class WordCountWithMapList {
//path为需要统计的文件存储路径
    public static Map<String,Integer> wordcount(String path) throws IOException {
    //声明一个Map<String,Integer>用于统计单词出现的次数,Key是单词,Value是单词出现次数
        Map<String,Integer> map = new HashMap();
        String line = null;
        BufferedReader br = new BufferedReader(new FileReader(path));
        //逐行读取文件内容,当行不为空时,对行内容按空格、制表符等进行分割
        while((line = br.readLine()) !=null){
            String[] words = line.split("\\s+");
            for(String word:words){
            //判断Map中是否已经有该条单词的记录,如果有则将Value加一,如果没有则将Key添加到Map中并将Value置为1
                if(map.containsKey(word))
                    map.put(word,map.get(word)+1);
                else
                    map.put(word,1);
            }
        }
        print(map);
        return map;
    }
    //写一个函数打印出Map内容
    public static void print(Map<String,Integer> map){
        for(Map.Entry<String,Integer> entry:map.entrySet()){
            System.out.println(entry.getKey()+"===="+entry.getValue());
        }
    }

    public static void main(String[] args) throws IOException {
        String path = "D:\\testio\\4\\news.txt";
        wordcount(path);
    }
}

MapReduce在Windows下实现

用到Hadoop的Jar包的项目首先需要引入四个依赖

    <dependency>
      <groupId>org.apache.hadoop</groupId>
      <artifactId>hadoop-common</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-hdfs</artifactId>
          <version>2.7.7</version>
      </dependency>
      <dependency>
          <groupId>org.apache.hadoop</groupId>
          <artifactId>hadoop-yarn</artifactId>
          <version>2.7.7</version>
      </dependency>

WordCount程序实现仅用到了hadoop-common和hadoop-client这两个依赖,但是为了日后方便扩展,建议同时添加以上四个依赖。
最基本的MapReduce由三个部分构成

  • Map:继承自hadoop-client中的Mapper类,按行读取文件数据,并以Key-value的方式发送到Reduce端
    在这里插入图片描述
    Mapper<参数一,参数二,参数三,参数四>
    参数一:必须为LongWritable的类型,是行偏移量,记录当前文件读到哪一行来了
    参数二:读取数据的类型,这里主要一定要用Hadoop提供的xxxWritable的类型,因为MapReduce之间的传输需要进行序列化和反序列化的操作,原生的基本数据类型和String类型无法胜任这样的工作
    参数三:Map完成之后输出的Value的类型
    参数四:Map完成之后输出的Key的类型
package SimpleTest.HadoopMRWindows;

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 MyMap extends Mapper<LongWritable, Text, Text, IntWritable> {
    Text mk = new Text();
    IntWritable mv = new IntWritable();

    @Override
    protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
        String line = value.toString();
        String[] words = line.split("\\s+");
        for(String word:words){
            mk.set(word);
            mv.set(1);
            context.write(mk,mv);
        }

    }
}
Map中需要做的事情

重写map方法,修改map方法的参数类型
map方法有三个参数
第一个参数是行偏移量,一般不需要修改
第二个参数就是读取的每一行的内容,一般需要对其进行分割,得到单个单词组成的String类型的数组
第三个参数是Context,主要用于Map和Reduce作业的提交

因为map是有多少行就调用多少次,所以为了提高程序的效率节约内存空间,一些对象的声明我们可以放在方外运行

  • Reduce
    在这里插入图片描述
    Reducer<参数一,参数二,参数三,参数四>
    参数一:从Map端接收过来的Key的类型,应与Map的输出Key类型一致
    参数二:从Map端接收过来的value的类型,应与Map的输出value类型一致
    参数三:Reduce的输出Key的类型
    参数四:Reduce的输出Value的类型
package SimpleTest.HadoopMRWindows;

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

import java.io.IOException;

public class MyReduce extends Reducer<Text,IntWritable,Text,IntWritable> {
    IntWritable mv = new IntWritable();
    @Override
    protected void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
        int sum = 0;
        for (IntWritable v:values){
            sum+=v.get();
        }
        mv.set(sum);
        context.write(key,mv);
    }
}

Reduce中需要做的事情

重写reduce方法
reduce方法也有三个参数
第一个参数:输入的Key
第二个参数:输入Key对应Value的迭代器
例如:一个input.txt文件中有两行内容
hello hello bye sup hello
dude guy homie hello
那么执行Key为hello的Reduce时,对应hello的值的迭代器的{(1),(1),(1),(1)}
第三个参数:用于提交作业,提交时同样以Key-Value键值对的形式提交

在Reduce中我们做的主要事情还是把迭代器中的值进行一个整合

  • Driver
package SimpleTest.HadoopMRWindows;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
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 MyDriver {
    public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {

        String input = "D:\\testio\\4\\";
        String output = "D:\\testio\\4out\\";
        Path ip = new Path(input);
        Path op = new Path(output);
//声明conf对象,用conf对象去构造一个job,用job设置各种运行类
        Configuration conf = new Configuration();
        Job job = Job.getInstance(conf);
//指定Driver所在类
        job.setJarByClass(MyDriver.class);
        //指定Map所在类
        job.setMapperClass(MyMap.class);
        //指定Reduce所在类
        job.setReducerClass(MyReduce.class);
		//指定Map输出的Key和Value的类型
        job.setMapOutputKeyClass(Text.class);
        job.setMapOutputValueClass(IntWritable.class);
		//指定Reduce输出的Key和Value类型
        job.setOutputValueClass(Text.class);
        job.setOutputKeyClass(IntWritable.class);
		//指定读取文件路径
        FileInputFormat.addInputPath(job,ip);
        //指定文件输出路径,这个路径下必须为空,否则会报错
        FileOutputFormat.setOutputPath(job,op);
		//如果该路径下存在文件,则删除文件
        FileSystem fs = FileSystem.get(conf);
        if(fs.exists(op)){
            fs.delete(op,true);
        }
		//运行,并等待运行完成
        job.waitForCompletion(true);
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值