一、mapreduce多job串联

1、需求

一个稍复杂点的处理逻辑往往需要多个 mapreduce 程序串联处理,多 job 的串联可以借助 mapreduce 框架的 JobControl 实现

2、实例

以下有两个 MapReduce 任务,分别是 Flow 的 SumMR 和 SortMR,其中有依赖关系: SumMR 的输出是 SortMR 的输入,所以 SortMR 的启动得在 SumMR 完成之后

public static void main(String[] args) throws Exception {
Configuration conf = new Configuration();
Job jobsum = Job.getInstance(conf);
jobsum.setJarByClass(RunManyJobMR.class);
jobsum.setMapperClass(FlowSumMapper.class);
jobsum.setReducerClass(FlowSumReducer.class);
jobsum.setMapOutputKeyClass(Text.class);
jobsum.setMapOutputValueClass(Flow.class);
jobsum.setCombinerClass(FlowSumReducer.class);
jobsum.setOutputKeyClass(Text.class);
jobsum.setOutputValueClass(Text.class);
FileInputFormat.setInputPaths(jobsum, "d:/flow/input");
FileOutputFormat.setOutputPath(jobsum, new Path("d:/flow/output12"));<br>
Job jobsort = Job.getInstance(conf);
jobsort.setJarByClass(RunManyJobMR.class);
jobsort.setMapperClass(FlowSortMapper.class);
jobsort.setReducerClass(FlowSortReducer.class);
jobsort.setMapOutputKeyClass(Flow.class);
jobsort.setMapOutputValueClass(Text.class);
jobsort.setOutputKeyClass(NullWritable.class);
jobsort.setOutputValueClass(Flow.class);
FileInputFormat.setInputPaths(jobsort, "d:/flow/output12");
FileOutputFormat.setOutputPath(jobsort, new Path("d:/flow/sortoutput12"));<br>
ControlledJob sumcj = new ControlledJob(jobsum.getConfiguration());
ControlledJob sortcj = new ControlledJob(jobsort.getConfiguration());
sumcj.setJob(jobsum);
sortcj.setJob(jobsort);
// 设置作业依赖关系
sortcj.addDependingJob(sumcj);
JobControl jc = new JobControl("flow sum and sort");
jc.addJob(sumcj);
jc.addJob(sortcj);
Thread jobThread = new Thread(jc);
jobThread.start();
while(!jc.allFinished()){
Thread.sleep(500);
}
jc.stop();
}

二、topn算法实现——自定义GroupComparator

1、需求

在统计学生成绩的小项目中,现在有一个需求:
   求出每个班参考学生成绩最高的学生的信息,班级,姓名和平均分

2、分析

(1)利用“班级和平均分”作为 key,可以将 map 阶段读取到的所有学生成绩数据按照班级 和成绩排倒序,发送到 reduce
(2)在 reduce 端利用 GroupingComparator 将班级相同的 kv 聚合成组,然后取第一个即是最 大值
   3、实现

数据类似于

computer    huangxiaoming   85  86  41  75  93  42  85
computer xuzheng 54 52 86 91 42
computer huangbo 85 42 96 38
english zhaobenshan 54 52 86 91 42 85 75
english liuyifei 85 41 75 21 85 96 14
algorithm liuyifei 75 85 62 48 54 96 15
computer huangjiaju 85 75 86 85 85
english liuyifei 76 95 86 74 68 74 48

第一步:先把分组和排序字段都综合到一个自定义对象里

package com.ghgj.mr.topn;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import org.apache.hadoop.io.WritableComparable;
public class ClazzScore implements WritableComparable<ClazzScore>{
private String clazz;
private Double score;
public String getClazz() {
return clazz;
}
public void setClazz(String clazz) {
this.clazz = clazz;
}
public Double getScore() {
return score;
}
public void setScore(Double score) {
this.score = score;
}
public ClazzScore(String clazz, Double score) {
super();
this.clazz = clazz;
this.score = score;
}
public ClazzScore() {
super();
// TODO Auto-generated constructor stub
}
@Override
public String toString() {
return clazz + "\t" + score;
}
@Override
public void write(DataOutput out) throws IOException {
out.writeUTF(clazz);
out.writeDouble(score);
}
@Override
public void readFields(DataInput in) throws IOException {
// TODO Auto-generated method stub
this.clazz = in.readUTF();
this.score = in.readDouble();
}
/**
* key 排序
*/
@Override
public int compareTo(ClazzScore cs) {
int it = cs.getClazz().compareTo(this.clazz);
if(it == 0){
return (int) (cs.getScore() - this.score);
}else{
return it;
}
}
}

第二步:编写排序之后的 ClazzScore 数据传入 ReduceTask 的分组规则

package com.ghgj.mr.topn;
import org.apache.hadoop.io.WritableComparable;
import org.apache.hadoop.io.WritableComparator;
public class ClazzScoreGroupComparator extends WritableComparator{
ClazzScoreGroupComparator(){
super(ClazzScore.class, true);
}
/**
* 决定输入到 reduce 的数据的分组规则
*/
@Override
public int compare(WritableComparable a, WritableComparable b) {
// TODO Auto-generated method stub
ClazzScore cs1 = (ClazzScore)a;
ClazzScore cs2 = (ClazzScore)b;
int it = cs1.getClazz().compareTo(cs2.getClazz());
return it;
}
}

第三步:编写mapreduce程序

package com.ghgj.mr.topn;
import java.io.IOException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.DoubleWritable;
import org.apache.hadoop.io.LongWritable;
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;
/**
* TopN 问题
*/
public class ScoreTop1MR {
public static void main(String[] args) throws Exception {
Configuration conf = new Configuration();
Job job = Job.getInstance(conf);
job.setJarByClass(ScoreTop1MR.class);
job.setMapperClass(ScoreTop1MRMapper.class);
job.setReducerClass(ScoreTop1MRReducer.class);
job.setOutputKeyClass(ClazzScore.class);
job.setOutputValueClass(DoubleWritable.class);
// 设置传入 reducer 的数据分组规则
job.setGroupingComparatorClass(ClazzScoreGroupComparator.class);
FileInputFormat.setInputPaths(job, "d:/score_all/input");
Path p = new Path("d:/score_all/output1");
FileSystem fs = FileSystem.newInstance(conf);
if(fs.exists(p)){
fs.delete(p, true);
}
FileOutputFormat.setOutputPath(job, p);
boolean status = job.waitForCompletion(true);
System.exit(status ? 0 : 1);
}
static class ScoreTop1MRMapper extends Mapper<LongWritable, Text, ClazzScore,
DoubleWritable>{
@Override
protected void map(LongWritable key, Text value, Context context) throws IOException,
InterruptedException {
String[] splits = value.toString().split("\t");
ClazzScore cs = new ClazzScore(splits[0], Double.parseDouble(splits[2]));
context.write(cs, new DoubleWritable(Double.parseDouble(splits[2])));
}
}
static class ScoreTop1MRReducer extends Reducer<ClazzScore, DoubleWritable, ClazzScore,
DoubleWritable>{
@Override
protected void reduce(ClazzScore cs, Iterable<DoubleWritable> scores, Context
context) throws IOException, InterruptedException {
// 按照规则,取每组的第一个就是 Top1
context.write(cs, scores.iterator().next());
}
}
}

三、Mapreduce全局计数器

1、需求

在实际生产代码中,常常需要将数据处理过程中遇到的不合规数据行进行全局计数,类似这 种需求可以借助 MapReduce 框架中提供的全局计数器来实现
     2、实例

以下是一个利用全局计数器来统计一个目录下所有文件出现的单词总数和总行数

package com.ghgj.mr.counter;

import java.io.IOException;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
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.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat; public class WordCount { enum MyWordCounter{COUNT_LINES,COUNT_WORD}
// enum Weekday{MONDAY, TUESDAY, WENSDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY} public static void main(String[] args) throws Exception {
// 指定hdfs相关的参数
Configuration conf = new Configuration();
Job job = Job.getInstance(conf);
// 设置jar包所在路径
job.setJarByClass(WordCount.class);
job.setMapperClass(WCMapper.class);
job.setReducerClass(WCReducer.class); // 指定reducetask的输出类型
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(LongWritable.class); // 本地路径
Path inputPath = new Path("d:/wordcount/input");
Path outputPath = new Path("d:/wordcount/output"); FileSystem fs = FileSystem.get(conf);
if(fs.exists(outputPath)){
fs.delete(outputPath, true);
}
FileInputFormat.setInputPaths(job, inputPath);
FileOutputFormat.setOutputPath(job, outputPath); // 最后提交任务
boolean waitForCompletion = job.waitForCompletion(true);
System.exit(waitForCompletion?0:1);
} private static class WCMapper extends Mapper<LongWritable, Text, Text, LongWritable>{
@Override
protected void map(LongWritable key, Text value, Context context)
throws IOException, InterruptedException { // COUNT_LINES++;
context.getCounter(MyWordCounter.COUNT_LINES).increment(1L); // 在此写maptask的业务代码
String[] words = value.toString().split(" ");
for(String word: words){
context.write(new Text(word), new LongWritable(1));
context.getCounter(MyWordCounter.COUNT_WORD).increment(1L);
}
}
} private static class WCReducer extends Reducer<Text, LongWritable, Text, LongWritable>{
@Override
protected void reduce(Text key, Iterable<LongWritable> values, Context context)
throws IOException, InterruptedException {
// 在此写reducetask的业务代码
long sum = 0;
for(LongWritable v: values){
sum += v.get();
}
context.write(key, new LongWritable(sum));
}
}
}

或者:另一种情况

package com.ghgj.mr.counter;
import java.io.IOException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
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.Mapper;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
public class CounterWordCount {
enum CouterWordCountC{COUNT_WORDS, COUNT_LINES}
public static void main(String[] args) throws Exception {
// 指定 hdfs 相关的参数
Configuration conf = new Configuration();
Job job = Job.getInstance(conf);
// 设置 jar 包所在路径
job.setJarByClass(CounterWordCount.class);
job.setMapperClass(WCCounterMapper.class);
job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(LongWritable.class);
// 本地路径
Path inputPath = new Path("d:/wordcount/input");
FileInputFormat.setInputPaths(job, inputPath);
job.setNumReduceTasks(0);
Path outputPath = new Path("d:/wordcount/output");
FileSystem fs = FileSystem.get(conf);
if(fs.exists(outputPath)){
fs.delete(outputPath, true);
}
FileOutputFormat.setOutputPath(job, outputPath);
// 最后提交任务
boolean waitForCompletion = job.waitForCompletion(true);
System.exit(waitForCompletion?0:1);
}
private static class WCCounterMapper extends Mapper<LongWritable, Text, Text,
LongWritable>{
@Override
protected void map(LongWritable key, Text value, Context context)
throws IOException, InterruptedException {
// 统计行数,因为默认读取文本是逐行读取,所以 map 执行一次,行数+1
context.getCounter(CouterWordCountC.COUNT_LINES).increment(1L);
String[] words = value.toString().split(" ");
for(String word: words){
// 统计单词总数,遇见一个单词就+1
context.getCounter(CouterWordCountC.COUNT_WORDS).increment(1L);
}
}
}
}

参考:https://www.cnblogs.com/liuwei6/p/6724070.html

mapreduce 函数入门 三的更多相关文章

  1. mapreduce 函数入门 二

    m apreduce三大组件:Combiner\Sort\Partitioner 默认组件:排序,分区(不设置,系统有默认值) 一.mapreduce中的Combiner 1.什么是combiner ...

  2. mapreduce 函数入门 一

    MapReduce 程序的业务编码分为两个大部分,一部分配置程序的运行信息,一部分 编写该 MapReduce 程序的业务逻辑,并且业务逻辑的 map 阶段和 reduce 阶段的代码分别继 承 Ma ...

  3. MongoDB入门三步曲2--基本操作(续)--聚合、索引、游标及mapReduce

    mongodb 基本操作(续)--聚合.索引.游标及mapReduce 目录 聚合操作 MapReduce 游标 索引 聚合操作 像大多关系数据库一样,Mongodb也提供了聚合操作,这里仅列取常见到 ...

  4. Swift语法基础入门三(函数, 闭包)

    Swift语法基础入门三(函数, 闭包) 函数: 函数是用来完成特定任务的独立的代码块.你给一个函数起一个合适的名字,用来标识函数做什么,并且当函数需要执行的时候,这个名字会被用于“调用”函数 格式: ...

  5. javascript封装函数入门

    封装函数的入门 一.使用函数有两步: 1.定义函数,又叫声明函数, 封装函数. 定义函数的三个要素:功能,参数,返回值. function 函数名(形参){ 函数代码 return 结果} //2.调 ...

  6. python之函数入门

    python之函数入门 一. 什么是函数 二. 函数定义, 函数名, 函数体以及函数的调用 三. 函数的返回值 四. 函数的参数 五.函数名->第一类对象 六.闭包 一,什么是函数 函数: 对代 ...

  7. C语言第七讲,函数入门.

    C语言第七讲,函数入门. 一丶了解面向过程和面向对象的区别. 为什么要先讲面向过程和面向对象的区别? 面向过程,就是什么都要自己做.  比如你要吃饭. 那么你得自己做饭. 面向对象, 面向对象就是我要 ...

  8. C#基础入门 三

    C#基础入门 三 类 类使用class关键字进行声明,前面加一个访问修饰符,public class car{} 访问修饰符:修师傅可以用来修饰类和类成员等,控制它们的可见度 修饰符关键字分别为:pu ...

  9. redis入门(三)

    目录 redis入门(三) 目录 前言 事务 原理 Lua脚本 安装 脚本命令 集群搭建工具 redis-trib.rb redis官方集群搭建 集群横向扩展 故障转移 redis管理 参考文档 re ...

随机推荐

  1. Go 笔记之如何防止 goroutine 泄露

    今天来简单谈谈,Go 如何防止 goroutine 泄露. 概述 Go 的并发模型与其他语言不同,虽说它简化了并发程序的开发难度,但如果不了解使用方法,常常会遇到 goroutine 泄露的问题.虽然 ...

  2. 从零开始一步一步搭建Ubuntu Server服务器、修改数据源、安装Docker、配置镜像加速器、Compose部署Gitlab服务

    场景 最终目的是使用Docker Compose部署一个Gitlab服务. 效果 注: 博客: https://blog.csdn.net/badao_liumang_qizhi关注公众号 霸道的程序 ...

  3. mysql 存储过程 函数 触发器

    mysql存储过程与函数 存储过程下载  demo mysql> delimiter // -- 这里//为修改默认分隔符: mysql> CREATE PROCEDURE simplep ...

  4. iOS应用开发应遵循的10条设计原则

    转自:http://mobile.51cto.com/design-309719.htm 1.操控便捷 iOS应用的控制设计应该具有圆润的轮廓和程式化的梯度,操作便捷. 2.结构清晰.导航方便 充分利 ...

  5. When does VideoToolbox' VTCompressionSession benefit from hardware acceleration?

    来源:http://stackoverflow.com/questions/19256897/when-does-videotoolbox-vtcompressionsession-benefit-f ...

  6. Global variable in ABAP function group

    Function group is loaded into runtime memory by the FIRST call of a function module inside this func ...

  7. MySQL——基本概念

    1.数据库:是一个长期存储在计算机内的.有组织的.有共享的.统一管理的数据集合.它是一个按数据结构来存储的和管理数据的计算机软件系统,即数据库包含两层含义:保管数据的“仓库”,以及数据管理的方法和技术 ...

  8. python中os与sys作用与区别

    https://www.cnblogs.com/cloak/p/11237285.html OS模块 在自动化测试中,经常需要查找操作文件,比如说查找配置文件(从而读取配置文件的信息),查找测试报告( ...

  9. Tram POJ - 1847

    题目链接:https://vjudge.net/problem/POJ-1847 思路:想从A到B使用开关少,想清楚了就是个简单的最短路,可以把不用开开关为权值0, 要开开关为权值1,就是求A到B开开 ...

  10. MySQL服务启动时显示本地计算机上的MySQL服务启动后停止。某些服务在。。。

    之前一直用的好端端的,这次启动服务突然就报了这错误. 更好的阅读体验可访问 这里. 起因 为了使用 LOAD_FILE 函数,在数据库配置文件 my.ini的 [mysqld] 里添加 secure_ ...