一:特殊用法

我们上来不讲普通用法,普通用法放到最后。我们来谈一谈特殊用法,了解这一用法,让你的mapreduce编程能力提高一个档次,毫不夸张!!!扯淡了,让我们进入正题:

我们知道reduce和map都有一个局限性就是map是读一行执行一次,reduce是每一组执行一次

但是当我们想全部得到数据之后,按照需求删选然后再输出怎么办?

这时候只使用map和reduce显然是达不到目的的?

那该怎么呢?这时候我们想到了 setUp和cleanUp的特性,只执行一次。

这样我们对于最终数据的过滤,然后输出要放在cleanUp中。这样就能实现对数据,不一组一组输出,而是全部拿到,最后过滤输出。经典运用常见,mapreduce分析数据然后再求数据的topN 问题。

以求出单词出现次数前三名为例

MAPREDUCE求topn问题

以wordcount为例,求出单词出现数量前三名
数据:

love you do

you like me

me like you do

love you do

you like me

me like you do

love you do

you like me

me like you do

love you do

you like me

分析:

我们知道mapreduce有分许聚合的功能,所以第一步就是:

把每个单词读出来,然后在reduce中聚合,求出每个单词出现的次数

但是怎么控制只输出前三名呢?

我们知道,map是读一行执行一次,reduce是每一组执行一次

所以只用map,和reduce是无法控制输出的次数的

但是我们又知道,无论map或者reduce都有 setUp 和cleanUp而且这两个执行一次

所以我们可以在reduce阶段把每一个单词当做key,单词出现的次数当做value,每一组存放到一个map里面,此时只存,不写出。在reduce的cleanUp阶段map排序,然后输出前三名

代码:

maper代码

public class WcMapper extends Mapper<LongWritable, Text, Text, IntWritable> {

@Override

protected void map(LongWritable key, Text value, Mapper<LongWritable, Text, Text, IntWritable>.Context context)

throws IOException, InterruptedException {

String[] split = value.toString().split(" ");

for (String word : split) {

context.write(new Text(word), new IntWritable(1));

}

}

}

reduce代码

public class WcReducer extends Reducer<Text, IntWritable, Text, IntWritable>{

Map<String,Integer> map=new HashMap<String, Integer>();

protected void reduce(Text key, Iterable<IntWritable> iter,

Reducer<Text, IntWritable, Text, IntWritable>.Context conext) throws IOException, InterruptedException {

int  count=0;

for (IntWritable wordCount : iter) {

count+=wordCount.get();

}

String name=key.toString();

map.put(name, count);

}

@Override

protected void cleanup(Reducer<Text, IntWritable, Text, IntWritable>.Context context)

throws IOException, InterruptedException {

//这里将map.entrySet()转换成list

List<Map.Entry<String,Integer>> list=new LinkedList<Map.Entry<String,Integer>>(map.entrySet());

//通过比较器来实现排序

Collections.sort(list,new Comparator<Map.Entry<String,Integer>>() {

//降序排序

@Override

public int compare(Entry<String, Integer> arg0,Entry<String, Integer> arg1) {

return (int) (arg1.getValue() - arg0.getValue());

}

});

for(int i=0;i<3;i++){

context.write(new Text(list.get(i).getKey()), new IntWritable(list.get(i).getValue()));

}

}}

job客户端代码

public class JobClient{
public static void main(String[] args) throws Exception {
Configuration conf = new Configuration();
//conf.set("fs.defaultFS", "hdfs://wangzhihua1:9000/");
conf.set("mapreduce.framework", "local");
         Job job = Job.getInstance(conf);

// 封装本mr程序相关到信息到job对象中
//job.setJar("d:/wc.jar");
job.setJarByClass(JobClient.class);

// 指定mapreduce程序用jar包中的哪个类作为Mapper逻辑类
job.setMapperClass(WcMapper.class);
// 指定mapreduce程序用jar包中的哪个类作为Reducer逻辑类
job.setReducerClass(WcReducer.class);

// 告诉mapreduce程序,我们的map逻辑输出的KEY.VALUE的类型
job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(IntWritable.class);

// 告诉mapreduce程序,我们的reduce逻辑输出的KEY.VALUE的类型
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(IntWritable.class);

// 告诉mapreduce程序,我们的原始文件在哪里
FileInputFormat.setInputPaths(job, new Path("d:/wc/input/"));
// 告诉mapreduce程序,结果数据往哪里写
FileOutputFormat.setOutputPath(job, new Path("d:/wc/output/"));

// 设置reduce task的运行实例数
job.setNumReduceTasks(1); // 默认是1

// 调用job对象的方法来提交任务
job.submit();
}

}

二 常规用法

在hadoop的源码中,基类Mapper类和Reducer类中都是只包含四个方法:setup方法,cleanup方法,run方法,map方法。如下所示:

其方法的调用方式是在run方法中,如下所示:

  可以看出,在run方法中调用了上面的三个方法:setup方法,map方法,cleanup方法。其中setup方法和cleanup方法默认是不做任何操作,且它们只被执行一次。但是setup方法一般会在map函数之前执行一些准备工作,如作业的一些配置信息等;cleanup方法则是在map方法运行完之后最后执行 的,该方法是完成一些结尾清理的工作,如:资源释放等。如果需要做一些配置和清理的工作,需要在Mapper/Reducer的子类中进行重写来实现相应的功能。map方法会在对应的子类中重新实现,就是我们自定义的map方法。该方法在一个while循环里面,表明该方法是执行很多次的。run方法就是每个maptask调用的方

hadoop中的MapReduce框架里已经预定义了相关的接口,其中如Mapper类下的方法setup()和cleanup()。

setup(),此方法被MapReduce框架仅且执行一次,在执行Map任务前,进行相关变量或者资源的集中初始化工作。若是将资源初始化工作放在方法map()中,导致Mapper任务在解析每一行输入时都会进行资源初始化工作,导致重复,程序运行效率不高!

cleanup(),此方法被MapReduce框架仅且执行一次,在执行完毕Map任务后,进行相关变量或资源的释放工作。若是将释放资源工作放入方法map()中,也会导致Mapper任务在解析、处理每一行文本后释放资源,而且在下一行文本解析前还要重复初始化,导致反复重复,程序运行效率不高!
所以,建议资源初始化及释放工作,分别放入方法setup()和cleanup()中进行。

mapreduce的cleanUp和setUp的特殊用法(TopN问题)和常规用法的更多相关文章

  1. GridView的常规用法

    GridView控件在Asp.net中相当常用,以下是控件的解释,有些是常用的,有些是偶尔用到的,查找.使用.记录,仅此而已.(最后附带DropDownList控件) ASP.NET中GridView ...

  2. 子查询。ANY三种用法。ALL两种用法。HAVING中使用子查询。SELECT中使用子查询。

    子查询存在的意义是解决多表查询带来的性能问题. 子查询返回单行多列: ANY三种用法: ALL两种用法: HAVING中的子查询返回单行单列: SELECT中使用子查询:(了解就好,避免使用这种方法! ...

  3. entrySet用法 以及遍历map的用法

    entrySet用法 以及遍历map的用法   keySet是键的集合,Set里面的类型即key的类型entrySet是 键-值 对的集合,Set里面的类型是Map.Entry   1.keySet( ...

  4. LOG4NET用法(个人比较喜欢的用法)

    LOG4NET用法(个人比较喜欢的用法) http://fanrsh.cnblogs.com/archive/2006/06/08/420546.html

  5. 7.1 安装软件包的三种方法 7.2 rpm包介绍 7.3 rpm工具用法 7.4 yum工具用法 7.5 yum搭建本地仓库

    7.1 安装软件包的三种方法 7.2 rpm包介绍 7.3 rpm工具用法 7.4 yum工具用法 7.5 yum搭建本地仓库 三种方法 rpm工具----->类型windows下的exe程序 ...

  6. 【python】-matplotlib.pylab常规用法

    目的: 了解matplotlib.pylab常规用法 示例 import matplotlib.pylab as pl x = range(10) y = [i * i for i in x] pl. ...

  7. MarkDown的常规用法

    MarkDown的常规用法 标题 # 一级标题 ## 二级标题 ... ###### 六级标题 列表 第二级 - 和 空格 + 和 空额 * 和 空格 第三级 代码块 多行代码块 3个` 回车 单行代 ...

  8. Vuex 常规用法

    背景 很多时候我们已经熟悉了框架的运用,但是有时候就是忘了怎么用 所以这里想记下大部分的框架使用方法,方便使用的时候拷贝 一.安装 npm 方式 npm install vuex --save yar ...

  9. setUp和tearDown及setUpClass和tearDownClass的用法及区别

    ① setup():每个测试函数运行前运行 ② teardown():每个测试函数运行完后执行 ③ setUpClass():必须使用@classmethod 装饰器,所有test运行前运行一次 ④ ...

随机推荐

  1. UML标准建模语言与应用实例

    一.基本信息 标题:UML标准建模语言与应用实例 时间:2012 出版源:科技创新导报 领域分类:UML标准建模语言 面向对象 系统分析与设计 二.研究背景 问题定义:UML建模语言用图形来表现典型的 ...

  2. Codeforces828 A. Restaurant Tables

    A. Restaurant Tables time limit per test 1 second memory limit per test 256 megabytes input standard ...

  3. PMP:3.项目经理角色

    成员角色:整合指挥者 在团队中的职责:负终责 知识技能:综合技能&沟通   定义: 职能经理专注于对某个职能领域或业务部门的管理监督. 运营经理负责保证业务运营的高效性. 项目经理是由执行组织 ...

  4. C#实现录音录像录屏源码

    以前写过两篇录音和录像的文章(实现语音视频录制.在服务器端录制语音视频),最近有朋友问,如果要实现屏幕录制这样的功能,该怎么做了?实际上录屏的原理跟录音.录像是差不多的,如果了解了我前面两篇文章中介绍 ...

  5. 6. ASP.NET MVC 5.0 中的HTML Helper【HTML 帮助类】

    这篇文章,我将带领大家学习HTML Helper.[PS:上一篇-->5.ASP.NET MVC 中的Area[区域]是什么] HTML Helpers是用来创建HTML标签进而创建HTML控件 ...

  6. python中不同文件中函数和类的调用

    最近在学习Python的时候,遇到了一个不同文件中类无法调用的问题,搜了很多,发现很多人针对 这个问题都说的相当含糊,让我费了好大劲才把这个东东搞明白.记录一下,权且温习. 调用分两种,一种是同种文件 ...

  7. 转载 Python 正则表达式入门(初级篇)

    Python 正则表达式入门(初级篇) 本文主要为没有使用正则表达式经验的新手入门所写.转载请写明出处 引子 首先说 正则表达式是什么? 正则表达式,又称正规表示式.正规表示法.正规表达式.规则表达式 ...

  8. JavaScript中的关于this

    this在js中是一个特别的关键字,被自动保存在所有函数的作用域中. 为什么要用this this提供一个对象方式隐式传递一个对象的引用,因此可以将api设计的简洁并且容易复用.看下面两段代码的比较: ...

  9. Xamarin.Android 关于so包报错问题

    问题描述:使用so包时报错. 解决方法: 1.保证 libs > armeabi 和 armeabi-v7a 中的so包一致. 2.去掉 x86,x86_64,arm64-v8a. 3. so的 ...

  10. Linux学习笔记之五————Linux常用命令之用户、权限管理

    一.引言 用户是Unix/Linux系统工作中重要的一环,用户管理包括用户与组账号的管理. 在Unix/Linux系统中,不论是由本机或是远程登录系统,每个系统都必须拥有一个账号,并且对于不同的系统资 ...