与map端的模式类似,map端要重写Mapper方法,reduce端也要重写Reduce方法,这里有一个泛型,我们先看参数类型

分别对应输入keyin,valuein,keyout,valueout.。

  这里前两个参数:keyin,valueint就是map端处理以后的键值对。map端的逻辑我们已经写完了,在那个阶段,我们设置了以手机号为key,一个bean对象为value的键值对。但是map端还有其他的处理逻辑,设置完键值对以后,map还要把相同key的数据放在一起,打上分区标志(如果有分区的话),然后把相同分区的数据分发(shuffle)一个reduce里面。比如我们的原始数据有这么两个手机号:

13726230503112 00-FD-07-A4-72-B8:CMCC 120.196.100.82 i02.c.aliimg.com 24 27 2481 24681 200

13726230503112 5C-0E-8B-C7-F7-90:CMCC 120.197.40.4 rank.ie.sogou.com 搜索引擎 28 27 3659 3538 200,

  map端处理完以后,分发到reduce的数据格式是这样一个map集合:

map(

key:13726230503112

value{

  phoneNumber:13726230503112 ,upFlow:2481  downFlow:24681 ,sumFlow:27162

  phoneNumber:13726230503112 ,upFlow:3659 downFlow:3538 ,sumFlow:7179

}

)

reduce代码:

package MR.phone;

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

import java.io.IOException;

public class FlowReduce extends Reducer<Text,PhoneBean,Text,PhoneBean> {
@Override
protected void reduce(Text key, Iterable<PhoneBean> values, Reducer<Text, PhoneBean, Text, PhoneBean>.Context context) throws IOException, InterruptedException {
//遍历所有的PnoneBean,将其上下行流量进行累加计算,计算完之后封装数据,写出
long sum_upflow=0;
long sum_downflow=0;
long sum_flow=0;
for (PhoneBean flow : values) {
sum_upflow=sum_upflow+flow.getUpFlow();
sum_downflow=sum_downflow+ flow.getDownFlow();
sum_flow=sum_flow+flow.getSumFlow();
}
//封装数据,写出
PhoneBean result_flow=new PhoneBean(sum_upflow,sum_downflow,sum_flow);
context.write(key,result_flow);

}
}

这里的代码逻辑计较简单,注意我们这里封装valueout的时候,用的有参构造, 注意bean里面要有有参构造。但是整个一个map——shuffl——reduce过程基本就是这样了。现在回过头看map-reduce的流程图,会清晰很多。

现在剩下的问题就是搞个Driver(固定套路),测试一下我们的代码逻辑:

package MR.phone;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
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 FlowDriver {
public static void main(String[] args) throws IOException, InterruptedException, ClassNotFoundException {
//1,获取配置信息,设置job
Configuration conf = new Configuration();
Job job = Job.getInstance(conf);

//设置job
job.setJarByClass(FlowDriver.class);

//设置map
job.setMapperClass(FlowMapper.class);
job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(PhoneBean.class);

//设置reduce
job.setReducerClass(FlowReduce.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(PhoneBean.class);

//设置路径
FileInputFormat.setInputPaths(job,new Path("D:\\bigadatapra\\phone_data.txt"));
FileOutputFormat.setOutputPath(job,new Path("D:\\bigadatapra\\output041801"));

//提交job
boolean result = job.waitForCompletion(true);

System.exit(result?0:1);

}

}

如果配置好本地Hadoop环境的话,直接运行main函数就能看见结果了。



reduce累加实现的更多相关文章

  1. python 练习用python六剑客实现一个统计数字的个数,六剑客:(map、lambda、reduce、filter、切片、推到列表)

    统计一共有几个数字 s="sdfa45ads46723" #lambda >>> filter(lambda x:x.isdigit(),list(s)) ['4 ...

  2. 第七十九篇:数组方法(forEach,some,every,reduce)

    好家伙,来复习几个数组方法, 1.forEach循环与some循环 代码如下: <script> const arr =['奔驰','宝马','GTR','奥迪'] //forEach循环 ...

  3. python test

    #!/usr/bin/env python #-*- encoding: utf- -*- ''' def foo(name): print name, '去砍柴' foo('yangshanlei: ...

  4. Python序列函数、高级特性及高阶函数

    序列函数: enumerate: for循环时记录索引,逐个返回元组(i, item) sorted:返回新的有序列表 zip:压缩将多个序列的对应位置的元素组成元组 zip(*元组列表): 解压缩 ...

  5. 使用javascript模拟常见数据结构(一)

    数据结构和算法可算是每个程序员的必备技能,而随着前端工作的深入,对于数据结构的知识真的是越来越需要掌握了.好了,于是乎最近看了<javascript数据结构和算法>,算是对于后面的使用C语 ...

  6. simrank

    simrank 背景 度量相似度是许多应用的关键问题.传统方法与问题的领域相关,如文本匹配.计算交集.simrank则利用关联关系度量相似性,即"两个节点的相似性和各自邻域节点的相似度有关& ...

  7. ES5拓展

    一.JSON拓展 1.JSON.parse(str,fun):将JSON字符串转为js对象 两个参数:str表示要处理的字符串:fun处理函数,函数有两个参数,属性名.属性值 // 定义json字符串 ...

  8. numpy_basic3

    矩陣 矩阵是numpy.matrix类类型的对象,该类继承自numpy.ndarray,任何针对多维数组的操作,对矩阵同样有效,但是作为子类矩阵又结合其自身的特点,做了必要的扩充,比如:乘法计算.求逆 ...

  9. js数组的遍历(API)

    1.for 循环 普通遍历方法,可优化,存下数组的length,避免每次都去获取数组的length,性能提升 for(var i=0;i<arr.length;i++){ console.log ...

随机推荐

  1. 消息队列,IPC机制(进程间通信),生产者消费者模型,线程及相关

    消息队列 创建 ''' Queue是模块multiprocessing中的一个类我们也可以这样导入from multiprocessing import Queue,创 建时queue = Queue ...

  2. Spring Boot 动态修改 log level

    引入依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>sp ...

  3. spring boot 中接口参数为枚举时的反序列化配置(总结)

    步骤 如果是 GET 请求中需要反序列化枚举值(即 url 中的参数[querystring]),确保以下两点 1.1. 重写 StringToEnumConverterFactory 1.2. 配置 ...

  4. 141. Linked List Cycle - LeetCode

    Question 141. Linked List Cycle Solution 题目大意:给一个链表,判断是否存在循环,最好不要使用额外空间 思路:定义一个假节点fakeNext,遍历这个链表,判断 ...

  5. Pandas 分组聚合 :分组、分组对象操作

    1.概述 1.1 group语法 df.groupby(self, by=None, axis=0, level=None, as_index: bool=True, sort: bool=True, ...

  6. java基础题(5)

    6.常用API 6.1string类 1.动态字符串 描述 将一个由英文字母组成的字符串转换成从末尾开始每三个字母用逗号分隔的形式. 输入描述: 一个字符串 输出描述: 修改后的字符串 示例1 输入: ...

  7. 且看这个Node全栈框架,实现了个Cli终端引擎,可无限扩充命令集

    背景介绍 一般而言,大多数框架都会提供Cli终端工具,用于通过命令行执行一些工具类脚本 CabloyJS提供的Cli终端工具却与众不同.更确切的说,CabloyJS提供的是Cli终端引擎,由一套Cli ...

  8. SQL语句修改MySQL用户密码

    SQL语句修改MySQL用户密码 前言 上数据库安全实验课,用命令行和DataGrip试图修改用户密码,一直语法报错.最后用Navicat才修改成功,预览Navicat的SQL语句,发现语句和网上都不 ...

  9. 漏洞修复之Oracle系列

    Oracle 11g CVE-2012-1675(远程投毒)漏洞修复. 数据库版本 Oracle 11g 11.2.0.4.0非RAC 漏洞编号 CVE-2012-1675 漏洞介绍 Oracle允许 ...

  10. Burnside 引理与 Pólya 定理

    群 群的定义 在数学中,群是由一种集合以及一个二元运算所组成的,符合"群公理"的代数结构. 一个群是一个集合 \(G\) 加上对 \(G\) 的二元运算.二元运算用 \(\cdot ...