最近在看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. ajax无刷新上传图片

    页面: <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> & ...

  2. [转] Oracle analyze 命令分析

    转自:http://blog.sina.com.cn/s/blog_682841ba0101bncp.html 1.analyze table t1 compute statistics for ta ...

  3. SDK,monkey 浅谈

    最近在工作之余碰到一些手机测试的新手,现在测试手机的基本都是android的系统. 然后在遇到压力测试的时候就开始遇到问题了. 压力测试用什么工具?怎么使用?工具怎么来? 今天遇到两个人都问我SDK是 ...

  4. Practice:输入年月日,判断该时间为一年的第几天

    #-*- coding:utf- -*- ''' Created on -- # 输入年月日,判断为一年的第几天 @author: AdministrInputator ''' def leapYea ...

  5. Daily Scrum 12.1

    今日完成任务: 完成了对源代码结构的修改,删除冗余等:和其他小组讨论了关于整合的问题,向其他小组介绍自己小组使用的数据库等. 明日任务: 晏旭瑞 初步完成文档上传下载 孙思权 深入了解数据库中每个表, ...

  6. Verilog之电平检测

    检测低电平为例 module detect_module ( CLK, RSTn, RX_Pin_In, H2L_Sig ); input CLK; input RSTn; input RX_Pin_ ...

  7. Bootstrap 基础学习笔记(一)

    排版 (1)标题 Bootstrap标题样式进行了以下显著的优化重置: 1.重新设置了margin-top和margin-bottom的值,  h1~h3重置后的值都是20px:h4~h6重置后的值都 ...

  8. centos6搭建VPN

    1,检查是否开启PPP #cat /dev/ppp cat: /dev/ppp: No such device or address //表示已经开启 2,安装ppp和iptables #yum in ...

  9. 由struts错误使用引发的漏洞,使用参数作为返回的文件路径或文件名,作为返回result 值

    该错误可以导致他人任意访问该路径下的任何文件. struts 文件 <?xml version="1.0" encoding="UTF-8" ?> ...

  10. SQL分页查询结果不一致

    今天遇到了SQL分页查询结果不一致的情况,一看代码,原来是没加排序查询!!分页查询最好加排序,且以唯一性高的字段进行排序,如ID,时间等,以保持每页查询结果的准确! PS:又帮别人擦屁股!!