【hadoop】MapReduce简单案例:WordCount

文章主要是介绍hadoop的mapreduce的一个小案例,主要是统计数据文本word.txt中每个单词出现的次数。

1、启动hadoop的dfs、yarn;

2、上传word.txt文件到hadoop的dfs中,可以使用命令或者用javaAPI上传

   命令上传 ,在当前文件目录下输入 : hadoop fs -put word.txt /word.txt;

     

  word.txt内容随意,博主的是:

      

3、打开eclipse,新建一个java项目,导入相关jar包(在hadoop下的的share目录中)

主要有这三个类:

1)WCMapper.java

package com.lxq.mapreduce;

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

import java.io.IOException;

/**
 * Created by Administrator on 2015/6/14.
 */
public class WCMapper extends Mapper<LongWritable,Text,Text,LongWritable>{

    @Override
    protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
        //读取数据
        String line = value.toString();
        //切分数据
        String[] words = line.split(" ");
        //遍历
        for (String word : words) {
            //每个单词作为key,记录1
            context.write(new Text(word),new LongWritable(1));
        }

    }
}

2)WCReducer

package com.lxq.mapreduce;

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

import java.io.IOException;

/**
 * Created by Administrator on 2015/6/14.
 */
public class WCReducer extends Reducer<Text,LongWritable,Text,LongWritable> {

    @Override
    protected void reduce(Text key, Iterable<LongWritable> values, Context context) throws IOException, InterruptedException {
        //接受数据
        //统计
        long counter = 0;
        for (LongWritable value : values) {
            counter += value.get();
        }
        //输出
        context.write(key,new LongWritable(counter));
    }

}

3)WordCount

package com.lxq.mapreduce;

import org.apache.hadoop.conf.Configuration;
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.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;

import java.io.IOException;

/**
 * Created by Administrator on 2015/6/14.
 */
public class WordCount {

    public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {

        //构建Job对象
        Job job = Job.getInstance(new Configuration());

        //设置main方法所在的类
        job.setJarByClass(WordCount.class);

        //设置Mapper相关属性
        job.setMapperClass(WCMapper.class);
        job.setMapOutputKeyClass(Text.class);
        job.setMapOutputValueClass(LongWritable.class);
        //设置读取源文件的路径,这里应该是hdfs的文件路径
        FileInputFormat.setInputPaths(job,new Path("/word.txt"));

        //设置Reducer相关属性
        job.setReducerClass(WCReducer.class);
        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(LongWritable.class);
        //设置计算结果的输出路径
        FileOutputFormat.setOutputPath(job,new Path("/wcout"));

        //提交任务 true 打印进度 false 不打印
        job.waitForCompletion(true);

    }

}

 

4.右键项目点击export,打包成jar

 

注:选择jar的入口

 

5.执行MapReduce

1)使用hadoop命令 执行刚才打包的jar。

2)可以看到类似于这样的一些输出信息:

 

3)执行完后,可以在hadoop 的 dfs根目录下看到输出结果目录

 

4)统计结果如下:

可以看到是 SUCCES ,代表成功了。点击下面的 part-r-xxxxx可以查看运算结果;

 

分别计算出了每个单词出现的次数。

 

6、MapReduce解释:

    Mapper解析:

    ① 读取文件输入内容后,解析成key-value对,对于输入文件的每一行,解析成key-value对,每一个键值对调用一次map函数,读入的键值对大概是这样的:

      <“偏移量”,“当前行”> ...;  字符的偏移量作为key,每一行作为value;

        那么在进入WCMapper 的 map 方法时的时候,接收到的数据大概是这样的:

        key = "0" , value = "hello hadoop",  因为“hello hadoop” 字符长度为12(换行不算)则下一对key-value为  <"13","hello lixiongqing"> , 如此类推;

    ②在WCMapper的 map 方法中,根据业务需求,编写业务逻辑,处理输入的key-value,转换成新的key-value;

       在Mapper的输出的新的key-value 中,把每个单词作为Key,value为1,就是每出现一次就记录一个1,便于之后的统计。

       *注:在这里Mapper会对输出key、value进行分区,对于不同分区的数据,按照key进行排序,分组,相同key的value放到一个集合中。

              这里的最终输出结果是:<key,{value1,value2,...}>,......

   

    Reducer解析:

        ①对多个map任务的输出,按照不同的分区,通过网络copy到不同的reduce节点。

        ②对于map任务的输出,进行合并,排序。在reduce函数中,编写业务逻辑,对于输入的key、value进行处理,转换成新的key、value;

           在案例中,map任务的输出大概是这样的:<"hello",{1,1,1,1,1,1}>,<"hadoop",{1}>,.....

           那么reduce方法接收的到 key = "hello" value为{1,1,1,1...}集合的一个迭代器

           输出新的key、value 大概是这样的:<"hello",5>,<"hadoop",1>.......

        ③把reduce的输出结果保存到文件中。

 

posted @ 2015-06-14 03:18  南国树下  阅读(491)  评论(0)    收藏  举报