最近在看google那篇经典的MapReduce论文,中文版可以参考孟岩推荐的 mapreduce 中文版 中文翻译

论文中提到,MapReduce的编程模型就是:

计算利用一个输入key/value对集,来产生一个输出key/value对集.MapReduce库的用户用两个函数表达这个计算:map和reduce.

用户自定义的map函数,接受一个输入对,然后产生一个中间key/value对集.MapReduce库把所有具有相同中间key I的中间value聚合在一起,然后把它们传递给reduce函数.

用户自定义的reduce函数,接受一个中间key I和相关的一个value集.它合并这些value,形成一个比较小的value集.一般的,每次reduce调用只产生0或1个输出value.通过一个迭代器把中间value提供给用户自定义的reduce函数.这样可以使我们根据内存来控制value列表的大小.

那么研究MapReduce,一般是从hadoop开始,研究编程语言,一般从helloworld开始,那么我们研究hadoop,就先从官方实例wordcount开始。

按照上面提到的编程模型:

用户自定义的map函数,接受一个输入对,然后产生一个中间key/value对集.MapReduce库把所有具有相同中间key I的中间value聚合在一起,然后把它们传递给reduce函数.

那么对于单词计数这个程序来说:

map函数对输入的文本进行分词处理,然后输出(单词, 1)这样的结果,例如“You are a young man”,输出的就是(you, 1), (are, 1) 之类的结果

 

代码如下:

class TokenizerMapper extends Mapper<Object, Text, Text, IntWritable> {
private final static IntWritable one = new IntWritable(1);
private Text word = new Text(); @Override
protected void map(Object key, Text value, Context context) throws IOException, InterruptedException {
StringTokenizer tokenizer = new StringTokenizer(value.toString());
while (tokenizer.hasMoreTokens())
{
word.set(tokenizer.nextToken());
context.write(word, one);
}
}
}

上面提到map函数的输入也是k-v堆,从模板参数中可以看出。这个map函数的输入K-V类型为 <Object, Text>

而map函数的输出类型为<Text, IntWritable>,而这恰好就是reduce函数的输入类型

 

reduce函数:

用户自定义的reduce函数,接受一个中间key I和相关的一个value集.它合并这些value,形成一个比较小的value集.一般的,每次reduce调用只产生0或1个输出value.通过一个迭代器把中间value提供给用户自定义的reduce函数.这样可以使我们根据内存来控制value列表的大小.

在单词计数中,我们把具有相同key的结果聚合起来:

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

reduce函数的第二个参数类型为Iterable<IntWritable>, 这是一堆value的集合,他们具有相同的key,reduce函数的意义就是将这些结果聚合起来。

例如(”hello“, 1)和(”hello“, 1)聚合为(”hello“, 2),后者可能再次和(”hello“, 3) (”hello“, 1),聚合为(”hello“, 7)

可以通过控制values的大小,防止内存溢出,合理使用内存。

reduce函数的结果存储到磁盘上,就是我们最终的结果。

 

完整的代码为:

package com.zhihu;

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.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat; import java.io.IOException;
import java.util.StringTokenizer; /**
* Created by guochunyang on 15/9/22.
*/
public class WordCount { public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
Configuration conf = new Configuration();
Job job = Job.getInstance(conf, "wordcount");
job.setJarByClass(WordCount.class); job.setMapperClass(TokenizerMapper.class);
job.setCombinerClass(IntSumReducer.class);
job.setReducerClass(IntSumReducer.class); job.setOutputKeyClass(Text.class);
job.setOutputValueClass(IntWritable.class); FileInputFormat.addInputPath(job, new Path("in"));
FileOutputFormat.setOutputPath(job, new Path("out")); job.waitForCompletion(true);
}
} class TokenizerMapper extends Mapper<Object, Text, Text, IntWritable> {
private final static IntWritable one = new IntWritable(1);
private Text word = new Text(); @Override
protected void map(Object key, Text value, Context context) throws IOException, InterruptedException {
StringTokenizer tokenizer = new StringTokenizer(value.toString());
while (tokenizer.hasMoreTokens())
{
word.set(tokenizer.nextToken());
context.write(word, one);
}
}
} class IntSumReducer extends Reducer<Text, IntWritable, Text, IntWritable> {
private IntWritable result = new IntWritable(); @Override
protected void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
int sum = 0;
for (IntWritable val : values){
sum += val.get();
}
result.set(sum);
context.write(key, result);
}
}

MapReduce之单词计数的更多相关文章

  1. 大数据【四】MapReduce(单词计数;二次排序;计数器;join;分布式缓存)

       前言: 根据前面的几篇博客学习,现在可以进行MapReduce学习了.本篇博客首先阐述了MapReduce的概念及使用原理,其次直接从五个实验中实践学习(单词计数,二次排序,计数器,join,分 ...

  2. 基于 MapReduce 的单词计数(Word Count)的实现

    完整代码: // 导入必要的包 import java.io.IOException; import java.util.StringTokenizer; import org.apache.hado ...

  3. hadoop笔记之MapReduce的应用案例(WordCount单词计数)

    MapReduce的应用案例(WordCount单词计数) MapReduce的应用案例(WordCount单词计数) 1. WordCount单词计数 作用: 计算文件中出现每个单词的频数 输入结果 ...

  4. HDFS 手写mapreduce单词计数框架

    一.数据处理类 package com.css.hdfs; import java.io.BufferedReader; import java.io.IOException; import java ...

  5. Hadoop分布环境搭建步骤,及自带MapReduce单词计数程序实现

    Hadoop分布环境搭建步骤: 1.软硬件环境 CentOS 7.2 64 位 JDK- 1.8 Hadoo p- 2.7.4 2.安装SSH sudo yum install openssh-cli ...

  6. Hadoop: 单词计数(Word Count)的MapReduce实现

    1.Map与Reduce过程 1.1 Map过程 首先,Hadoop会把输入数据划分成等长的输入分片(input split) 或分片发送到MapReduce.Hadoop为每个分片创建一个map任务 ...

  7. Spark: 单词计数(Word Count)的MapReduce实现(Java/Python)

    1 导引 我们在博客<Hadoop: 单词计数(Word Count)的MapReduce实现 >中学习了如何用Hadoop-MapReduce实现单词计数,现在我们来看如何用Spark来 ...

  8. Storm实现单词计数

    package com.mengyao.storm; import java.io.File; import java.io.IOException; import java.util.Collect ...

  9. 单词计数-MapReduceJob

    pom文件 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3. ...

随机推荐

  1. notepad++对systemverilog的支持

    找到notepad++根目录中的"langs.xml",用notepad++打开,并搜索"verilog",     找到后,修改后面那句话为ext=" ...

  2. nginx反向代理编译异常

    cc1: warnings being treated as errors /root/nginx_tcp_proxy_module/ngx_tcp.c: 在函数‘ngx_tcp_add_addrs’ ...

  3. hdu 5666 (大数乘法) Segment

    题目:这里 题意:在线段x+y=q与坐标轴围成的三角形中,求有多少个坐标为整数的点,答案模上p. 很容易就想到最后答案就是((q-1)*(q-2))/2然后模上p就是了,但是这个数字比较大,相乘会爆l ...

  4. Log4j基本用法

    基本使用方法: Log4j由三个重要的组件构成:日志信息的优先级,日志信息的输出目的地,日志信息的输出格式.日志信息的优先级从高到低有ERROR.WARN.INFO.DEBUG,分别用来指定这条日志信 ...

  5. jsAddress

    demo.html <!DOCTYPE html><html><head> <title>纯JS省市区联动</title> <scri ...

  6. Linux下设置网卡随系统启动

    在GUI下安装RHEL,在配置网卡的时候,有时候会忘了勾选网卡随系统自动启动,解决方法是系统启动后,打开网卡配置文件/etc/sysconfig/network-script/ifcfg-eth*,将 ...

  7. 团队作业week3

    请每个团队的成员划分各自的角色:PM.Dev.Test,并通过团队博客发布. 请每个团队给出团队贡献分的分配方法,团队贡献分总分数数为:20 * 团队人数.要求每两个人的分数都不相同.请在团队博客写出 ...

  8. (Python )控制流语句if、for、while

    这一节,我们将学习Python的控制流语句,主要包括if.for.while.break.continue 和pass语句 1. If语句 if语句也许是我们最熟悉的语句.其使用方法如下: x=inp ...

  9. PYTHON第三天

    PYTHON之路 七.基本的if判断 最简单的流程处理: if ...else If简单练习: #!/usr/bin/env  python # -*-coding:utf-8 -*- #if 基本表 ...

  10. iOS ViewController生命周期

    ViewController是view的controller,viewController的职责主要包括管理内部各个view的加载显示与卸载,同时负责与其他ViewController的通信和协调. ...