前文

MapReduce编程实例

@

前言

简介

讲解_Hadoop 中文网

Hadoop测试项目:HadoopDemo

注意事项

如果下载了HadoopDemo作为测试,用到HDFS_CRUD.java

需要提前准备winutils。最好对应版本。

单词统计 WordCount

WordCountMapper.java

package top.rabbitcrows.hadoop.mr;

import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper; import java.io.IOException; /**
* 这里就是MapReduce程序 Map阶段业务逻辑实现的类 Mapper<KEYIN, VALUEIN, KEYOUT, VALUEOUT>
* <p>
* KEYIN:表示mapper数据输入时key的数据类型,在默认读取数据组件下,叫作ImportFormat,它的行为是每行读取待处理的数据
* 读取一行,就返回一行给MR程序,这种情况下 KEYIN就表示每一行的起始偏移,因此数据类型是Long
* <p>
* VALUEIN:表示mapper数据输入的时候Value的数据类型,在默认读取数据组件下,
* valueIN就表示读取的一行内容 因此数据类型是String
* <p>
* KEYOUT:表示mapper阶段数据输出的时候key的数据类型,在本案例中输出的key是单词,因此数据类型是String
* ValueOUT:表示mapper阶段数据输出的时候value的数据类型,在本案例中输出的value是单次的此书,因此数据类型是Integer
* <p>
* 这里所说的数据类型String,Long都是JDK的自带的类型,
* 数据在分布式系统中跨网络传输就需要将数据序列化,默认JDK序列化时效率低下,因此
* 使用Hadoop封装的序列化类型。 long--LongWritable String --Text Integer intWritable ....
*
* @author LEHOSO
*/
public class WordCountMapper extends Mapper<LongWritable, Text, Text, IntWritable> {
/**
* 这里就是mapper阶段具体业务逻辑实现的方法 该方法的调用取决于读取数据的组件有没有给MR传入数据
* 如果有数据传入,每一个<k,v>对,map就会被调用一次
*/
@Override
protected void map(LongWritable key, Text value,
Mapper<LongWritable, Text, Text, IntWritable>.Context context)
throws IOException, InterruptedException {
// 拿到传入进来的一行内容,把数据类型转换为String
String line = value.toString();
// 将这行内容按照分隔符切割
String[] words = line.split(" ");
// 遍历数组,每出现一个单词就标记一个数组1 例如:<单词,1>
for (String word : words) {
// 使用MR上下文context,把Map阶段处理的数据发送给Reduce阶段作为输入数据
context.write(new Text(word), new IntWritable(1));
//第一行 hadoop hadoop spark 发送出去的是<hadoop,1><hadoop,1><spark,1>
}
}
}

WordCountReducer.java

package top.rabbitcrows.hadoop.mr;

import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer; import java.io.IOException; //都要继承Reducer 这就是我们所说的变成模型,只需要套模板就行了 /**
* 这里是MR程序 reducer阶段处理的类
* <p>
* KEYIN:就是Reducer阶段输入的数据key类型,对应Mapper阶段输出KEY类型 ,在本案例中就是单词
* <p>
* VALUEIN:就是Reducer阶段输入的数据value类型,对应Mapper阶段输出VALUE类型 ,在本案例中就是个数
* <p>
* KEYOUT:就是Reducer阶段输出的数据key类型,在本案例中,就是单词 Text
* <p>
* VALUEOUT:reducer阶段输出的数据value类型,在本案例中,就是单词的总次数
*
* @author LEHOSO
*/
public class WordCountReducer extends Reducer<Text, IntWritable, Text, IntWritable> { /**
* 这里是REDUCE阶段具体业务类的实现方法
* 第一行 hadoop hadoop spark 发送出去的是<hadoop,1><hadoop,1><spark,1>
* reduce接受所有来自Map阶段处理的数据之后,按照Key的字典序进行排序
* 按照key是否相同作一组去调用reduce方法
* 本方法的key就是这一组相同的kv对 共同的Key
* 把这一组的所有v作为一个迭代器传入我们的reduce方法
* <p>
* 迭代器:<hadoop,[1,1]>
*/
@Override
protected void reduce(Text key, Iterable<IntWritable> value,
Reducer<Text, IntWritable, Text, IntWritable>.Context context)
throws IOException, InterruptedException {
//定义一个计数器
int count = 0;
//遍历一组迭代器,把每一个数量1累加起来就构成了单词的总次数 //
for (IntWritable iw : value) {
count += iw.get();
}
context.write(key, new IntWritable(count));
}
}

WordCountCombiner.java

package top.rabbitcrows.hadoop.mr;

import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer; import java.io.IOException; public class WordCountCombiner extends Reducer<Text, IntWritable, Text, IntWritable> { @Override
protected void reduce(Text key, Iterable<IntWritable> values,
Reducer<Text, IntWritable, Text, IntWritable>.Context context)
throws IOException, InterruptedException {
// 1.局部汇总
int count = 0;
for (IntWritable v : values) {
count += v.get();
}
context.write(key, new IntWritable(count));
}
}

WordCountDriver.java

package top.rabbitcrows.hadoop.mr;

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.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat; /**
* Driver类就是MR程序运行的主类,本类中组装了一些程序运行时所需要的信息
* 比如:使用的Mapper类是什么,Reducer类,数据在什么地方,输出在哪里
*
* @author LEHOSO
*/
public class WordCountDriver { public static void main(String[] args) throws Exception {
// 通过Job来封装本次MR的相关信息
Configuration conf = new Configuration();
conf.set("mapreduce.framework.name", "local");
Job wcjob = Job.getInstance(conf); // 指定MR Job jar包运行主类
wcjob.setJarByClass(WordCountDriver.class);
// 指定本次MR所有的Mapper Reducer类
wcjob.setMapperClass(WordCountMapper.class);
wcjob.setReducerClass(WordCountReducer.class); // 设置我们的业务逻辑 Mapper类的输出 key和 value的数据类型
wcjob.setMapOutputKeyClass(Text.class);
wcjob.setMapOutputValueClass(IntWritable.class); // 设置我们的业务逻辑 Reducer类的输出 key和 value的数据类型
wcjob.setOutputKeyClass(Text.class);
wcjob.setOutputValueClass(IntWritable.class); //设置Combiner组件
wcjob.setCombinerClass(WordCountCombiner.class); // 指定要处理的数据所在的位置
FileInputFormat.setInputPaths(wcjob, new Path("input/mr"));
// 指定处理完成之后的结果所保存的位置
FileOutputFormat.setOutputPath(wcjob, new Path("output/mr")); // 提交程序并且监控打印程序执行情况
boolean res = wcjob.waitForCompletion(true);
System.exit(res ? 0 : 1);
}
}

MapReduce 经典案例——倒排索引

InvertedIndexMapper.java

package top.rabbitcrows.mr.InvertedIndex;

import org.apache.commons.lang3.StringUtils;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.lib.input.FileSplit; import java.io.IOException; /**
* @author LEHOSO
* @date 2021/11/2
* @apinote
*/
public class InvertedIndexMapper extends Mapper<LongWritable, Text, Text, Text> { //存储单词和文档名称
private static Text KeyInfo = new Text(); //存储词频,初始化为1
private static final Text valueInfo = new Text("1"); @Override
protected void map(LongWritable key, Text value, Mapper<LongWritable, Text, Text, Text>.Context context) throws IOException, InterruptedException {
String line = value.toString();
String[] fileds = StringUtils.split(line, " ");
//得到这行数据所在的文件切片
FileSplit fileSplit = (FileSplit) context.getInputSplit();
//根据文件切片得到文件名
String fileName = fileSplit.getPath().getName();
for (String filed : fileds) {
//key值由单词和文档名称组成,如“MapReduce:file1.txt”
KeyInfo.set(filed + ":" + fileName);
context.write(KeyInfo, valueInfo);
}
}
}

InvertedIndexCombiner.java

package top.rabbitcrows.mr.InvertedIndex;

import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer; import java.io.IOException; /**
* @author LEHOSO
* @date 2021/11/2
* @apinote
*/
public class InvertedIndexCombiner extends Reducer<Text, Text, Text, Text> { private static Text info = new Text();
//输入:<MapReduce:file3.txt{1,1}>
//输出:<MapReduce:file3.txt:2> @Override
protected void reduce(Text key, Iterable<Text> values, Reducer<Text, Text, Text, Text>.Context context) throws IOException, InterruptedException {
int sum = 0; //统计词频
for (Text value : values) {
sum += Integer.parseInt(value.toString());
}
int splitIndex = key.toString().indexOf(":");
//重新设置value值并由文档名称和词频组成
info.set(key.toString().substring(splitIndex + 1) + ":" + sum);
//重新设置key值为单词
key.set(key.toString().substring(0, splitIndex));
context.write(key, info);
}
}

InvertedIndexReducer.java

package top.rabbitcrows.mr.InvertedIndex;

import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer; import java.io.IOException; /**
* @author LEHOSO
* @date 2021/11/2
* @apinote
*/
public class InvertedIndexReducer extends Reducer<Text, Text, Text, Text> {
private static Text result = new Text();
//输入:<MapReduce:file3.txt:2}>
//输出:<MapReduce:file1.txt:1;file2.txt:1;file3.txt:2;> @Override
protected void reduce(Text key, Iterable<Text> values, Reducer<Text, Text, Text, Text>.Context context) throws IOException, InterruptedException {
//生成文档列表
String fileList = new String();
for (Text value : values) {
fileList += value.toString() + ";";
}
result.set(fileList);
context.write(key, result);
}
}

InvertedIndexDriver.java

package top.rabbitcrows.mr.InvertedIndex;

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; /**
* @author LEHOSO
* @date 2021/11/2
* @apinote
*/
public class InvertedIndexDriver { public static void main(String[] args)
throws IOException, ClassNotFoundException, InterruptedException {
Configuration conf = new Configuration();
// conf.set("mapreduce.framework.name", "local");
Job job = Job.getInstance(conf); job.setJarByClass(InvertedIndexDriver.class); job.setMapperClass(InvertedIndexMapper.class);
job.setReducerClass(InvertedIndexReducer.class);
job.setCombinerClass(InvertedIndexCombiner.class); job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(Text.class); // 指定要处理的数据所在的位置
FileInputFormat.setInputPaths(job,
new Path("input/InvertedIndex/"));
// 指定处理完成之后的结果所保存的位置
FileOutputFormat.setOutputPath(job,
new Path("output/InvertedIndex")); // 提交程序并且监控打印程序执行情况
boolean res = job.waitForCompletion(true);
System.exit(res ? 0 : 1);
}
}

MapReduce 经典案例——数据去重

DedupMapper.java

package top.rabbitcrows.mr.dedup;

import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper; import java.io.IOException; /**
* @author LEHOSO
* @date 2021/11/5
* @apinote
*/
public class DedupMapper extends Mapper<LongWritable, Text, Text, NullWritable> { private static Text field = new Text(); //<0,2021-11-1 a><11,2021-11-2 b>
@Override
protected void map(LongWritable key, Text value, Mapper<LongWritable, Text, Text, NullWritable>.Context context) throws IOException, InterruptedException {
field = value;
//NullWritable.get()方法设置空值
context.write(field, NullWritable.get());
// <2018-3-3 c,null> <2018-3-4 d,null> }
}

DedupReducer.java

package top.rabbitcrows.mr.dedup;

import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer; import java.io.IOException; /**
* @author LEHOSO
* @date 2021/11/5
* @apinote
*/
public class DedupReducer extends Reducer<Text, NullWritable,Text,NullWritable> {
//<2021-11-1,a,null><2021-11-2,b,null><2021-11-3,c,null> @Override
protected void reduce(Text key, Iterable<NullWritable> values, Reducer<Text, NullWritable, Text, NullWritable>.Context context) throws IOException, InterruptedException {
context.write(key,NullWritable.get());
}
}

DedupDriver.java

package top.rabbitcrows.mr.dedup;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.NullWritable;
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; /**
* @author LEHOSO
* @date 2021/11/5
* @apinote
*/
public class DedupDriver { public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
Configuration conf = new Configuration();
Job job = Job.getInstance(conf);
job.setJarByClass(DedupDriver.class);
job.setMapperClass(DedupMapper.class);
job.setReducerClass(DedupReducer.class); job.setOutputKeyClass(Text.class);
job.setMapOutputValueClass(NullWritable.class); FileInputFormat.setInputPaths(job, new Path("input/Dedup")); // 指定处理完成之后的结果所保存的位置
FileOutputFormat.setOutputPath(job, new Path("output/Dedup")); job.waitForCompletion(true); }
}

MapReduce 经典案例——TopN

TopNMapper.java

package top.rabbitcrows.mr.topN;

import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper; import java.io.IOException;
import java.util.TreeMap; /**
* @author LEHOSO
* @date 2021/11/5
* @apinote
*/
public class TopNMapper extends Mapper<LongWritable, Text, NullWritable, IntWritable> { private TreeMap<Integer, String> repToRecordMap = new TreeMap<Integer, String>(); // <0,10 3 8 7 6 5 1 2 9 4>
// <xx,11 12 17 14 15 20>
@Override
protected void map(LongWritable key, Text value, Mapper<LongWritable, Text, NullWritable, IntWritable>.Context context) throws IOException, InterruptedException {
String line = value.toString();
String[] nums = line.split(" ");
for (String num : nums) {
//读取每行数据写入TreeMap,超过5个就会移除最小的数值
repToRecordMap.put(Integer.parseInt(num), " ");
if (repToRecordMap.size() > 5) {
repToRecordMap.remove(repToRecordMap.firstKey());
}
}
} //重写cleanup()方法,读取完所有文件行数据后,再输出到Reduce阶段
@Override
protected void cleanup(Mapper<LongWritable, Text, NullWritable, IntWritable>.Context context) throws IOException, InterruptedException {
for (Integer i : repToRecordMap.keySet()) {
try {
context.write(NullWritable.get(), new IntWritable(i));
} catch (Exception e) {
e.printStackTrace();
}
}
}
}

TopNReducer.java

package top.rabbitcrows.mr.topN;

import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.mapreduce.Reducer; import java.io.IOException;
import java.util.Comparator;
import java.util.TreeMap; /**
* @author LEHOSO
* @date 2021/11/5
* @apinote
*/
public class TopNReducer extends Reducer<NullWritable, IntWritable, NullWritable, IntWritable> { private TreeMap<Integer, String> repToRecordMap = new TreeMap<Integer, String>(new Comparator<Integer>() { //返回一个基本类型的整型,谁大谁排后面.
//返回负数表示:o1 小于o2
//返回0表示:表示:o1和o2相等
//返回正数表示:o1大于o2。
public int compare(Integer a, Integer b) {
return b - a;
}
}); public void reduce(NullWritable key, Iterable<IntWritable> values, Context context)
throws IOException, InterruptedException {
for (IntWritable value : values) {
repToRecordMap.put(value.get(), " ");
if (repToRecordMap.size() > 5) {
repToRecordMap.remove(repToRecordMap.firstKey());
}
}
for (Integer i : repToRecordMap.keySet()) {
context.write(NullWritable.get(), new IntWritable(i));
}
}
}

TopNDriver.java

package top.rabbitcrows.mr.topN;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat; /**
* @author LEHOSO
* @date 2021/11/5
* @apinote
*/
public class TopNDriver { public static void main(String[] args) throws Exception {
Configuration conf = new Configuration();
Job job = Job.getInstance();
job.setJarByClass(TopNDriver.class);
job.setMapperClass(TopNMapper.class);
job.setReducerClass(TopNReducer.class);
job.setNumReduceTasks(1);
//map阶段输出的key
job.setMapOutputKeyClass(NullWritable.class);
//map阶段输出的value
job.setMapOutputValueClass(IntWritable.class);
//reduce阶段输出的key
job.setOutputKeyClass(NullWritable.class);
//reduce阶段输出的value
job.setMapOutputValueClass(IntWritable.class); FileInputFormat.setInputPaths(job, new Path("input/TopN/num.txt"));
FileOutputFormat.setOutputPath(job, new Path("output/TopN")); boolean res = job.waitForCompletion(true);
System.out.println(res ? 0 : 1); } }

Github下载地址

(HadoopDemo)[https://github.com/lehoso/HadoopDemo]

三、MapReduce编程实例的更多相关文章

  1. MapReduce编程实例6

    前提准备: 1.hadoop安装运行正常.Hadoop安装配置请参考:Ubuntu下 Hadoop 1.2.1 配置安装 2.集成开发环境正常.集成开发环境配置请参考 :Ubuntu 搭建Hadoop ...

  2. MapReduce编程实例5

    前提准备: 1.hadoop安装运行正常.Hadoop安装配置请参考:Ubuntu下 Hadoop 1.2.1 配置安装 2.集成开发环境正常.集成开发环境配置请参考 :Ubuntu 搭建Hadoop ...

  3. MapReduce编程实例4

    MapReduce编程实例: MapReduce编程实例(一),详细介绍在集成环境中运行第一个MapReduce程序 WordCount及代码分析 MapReduce编程实例(二),计算学生平均成绩 ...

  4. MapReduce编程实例3

    MapReduce编程实例: MapReduce编程实例(一),详细介绍在集成环境中运行第一个MapReduce程序 WordCount及代码分析 MapReduce编程实例(二),计算学生平均成绩 ...

  5. MapReduce编程实例2

    MapReduce编程实例: MapReduce编程实例(一),详细介绍在集成环境中运行第一个MapReduce程序 WordCount及代码分析 MapReduce编程实例(二),计算学生平均成绩 ...

  6. hadoop2.2编程:使用MapReduce编程实例(转)

    原文链接:http://www.cnblogs.com/xia520pi/archive/2012/06/04/2534533.html 从网上搜到的一篇hadoop的编程实例,对于初学者真是帮助太大 ...

  7. MapReduce编程实例

    MapReduce常见编程实例集锦. WordCount单词统计 数据去重 倒排索引 1. WordCount单词统计 (1) 输入输出 输入数据: file1.csv内容 hellod world ...

  8. hadoop之mapreduce编程实例(系统日志初步清洗过滤处理)

    刚刚开始接触hadoop的时候,总觉得必须要先安装hadoop集群才能开始学习MR编程,其实并不用这样,当然如果你有条件有机器那最好是自己安装配置一个hadoop集群,这样你会更容易理解其工作原理.我 ...

  9. Hadoop--mapreduce编程实例1

    前提准备: 1.hadoop安装运行正常.Hadoop安装配置请参考:Ubuntu下 Hadoop 1.2.1 配置安装 2.集成开发环境正常.集成开发环境配置请参考 :Ubuntu 搭建Hadoop ...

随机推荐

  1. 阿里云 Serverless 再升级,从体验上拉开差距

    差距都在细节上. Serverless 要成就云计算的下一个 10 年,不仅需要在技术上持续精进,也需要在产品体验上精耕细作. 近日,阿里云 Serverless 再度升级,发布了一系列围绕产品体验方 ...

  2. Ysoserial Commons Collections3分析

    Ysoserial Commons Collections3分析 写在前面 CommonsCollections Gadget Chains CommonsCollection Version JDK ...

  3. FastAPI 学习之路(七)字符串的校验

    系列文章: FastAPI 学习之路(一)fastapi--高性能web开发框架 FastAPI 学习之路(二) FastAPI 学习之路(三) FastAPI 学习之路(四) FastAPI 学习之 ...

  4. 2020.3.28-ICPC训练联盟周赛,选用试题:UCF Local Programming Contest 2016

    A.Majestic 10 签到题. #include<iostream> #include<cstdio> #include<cstring> #include& ...

  5. C 库函数源码

    github URL git://sourceware.org/git/glibc.git 码云 URL https://gitee.com/jason.R.xie/glibc.git

  6. diff算法深入一下?

    文章转自豆皮范儿-diff算法深入一下 一.前言 有同学问:能否详细说一下 diff 算法. 简单说:diff 算法是一种优化手段,将前后两个模块进行差异化比较,修补(更新)差异的过程叫做 patch ...

  7. Java:并发笔记-06

    Java:并发笔记-06 说明:这是看了 bilibili 上 黑马程序员 的课程 java并发编程 后做的笔记 5. 共享模型之无锁 本章内容 CAS 与 volatile 原子整数 原子引用 原子 ...

  8. Java:TreeMap类小记

    Java:TreeMap类小记 对 Java 中的 TreeMap类,做一个微不足道的小小小小记 概述 前言:之前已经小小分析了一波 HashMap类.HashTable类.ConcurrentHas ...

  9. UltraSoft - Alpha - Postmortem 事后分析

    Alpha阶段 Postmortem会议 设想和目标 我们的软件要解决什么问题?是否定义得很清楚?是否对典型用户和典型场景有清晰的描述? 主要是解决DDL提醒功能的问题,定义的比较清楚,对典型用户和典 ...

  10. OO电梯作业总结

    (一)第五次作业 一.设计思路 生产消费者模型,输入接口是producer,调度器是tray,电梯是customer.由于只有一架电梯,所以生产消费模型满足以下条件: 一个生产者,一个消费者 托盘不为 ...