1 简介
MapReduce是Hadoop中的一个用于海量数据运算的组件, 分布式并行对海量数据运算!
运算模型分为两步 :
第一步 Map阶段: 对待处理的海量数据分任务 , 默认按照文件的个数和大小分(HDFS数据存储逻辑切块),一个任务一个Maptask-->机器 ,关注点--> map阶段处理数据的逻辑 --输出中间结果(缓冲区)
中间:缓存区 接收map的输出, 分区(几个区 sst) , 区内排序 , 区内分组
分区: 为了给reduce分任务 , key.hashcode%reducenumber 相同规则的key在一个分区中
区内分组:相同规则的key 聚合
第二步 Reduce阶段: 对map阶段的处理数据结果做汇总聚合---> 关注点:聚合逻辑 ---输出最终结果(结果路径)
2 入门程序(统计单词个数)
2.1 步骤
1 编写Mapper的实现类 map方法{map阶段的逻辑}
2 编写Reducer的实现类 reduce(){聚合的逻辑}
3 编写启动类: 1) 本地测试运行 2)分布式运行
依赖
<dependencies>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-common</artifactId>
<version>2.8.5</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-hdfs</artifactId>
<version>2.8.5</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-mapreduce-client-core</artifactId>
<version>2.8.5</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-mapreduce-client-common</artifactId>
<version>2.8.5</version>
</dependency>
</dependencies>
2.2 MapTask类
- Mapper<KEYIN,VALUEIN,KEYOUT,VALUEOUT>
KEYIN:输入的key 默认处理的是文本文件 行的起始偏移量 Long类型----(HDP自己的序列化方式)--->LongWritable
VALUE:输入的value默认处理的是文本文件 行的内容(line) String类型----(HDP自己的序列化方式)--->TEXT
KEYOUT:Map阶段逻辑处理后输出的key ,需求中的key[a1 a1 c1 b1 a1] 单词String类型----(HDP自己的序列化方式)--->TEXT
VALUEOUT:Map阶段逻辑处理后输出value,需求中的key[a1 a1 c1 b1 a1] 个数1 Integer类型----(HDP自己的序列化方式)--->IntWritable
-
map(LongWritable key, Text value, Context context)
用于编写map逻辑的方法
一对输入KV执行一次,案例中一行执行一次
参数一 输入的key的内容 偏移量
参数二 输入的value的内容 line 重点处理它
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;
/**
* @Auther: 多易教育-行哥
* @Date: 2020/7/9
* @Description:
* map 阶段
* 1 读取数据 a.txt
* hello tom jim cat gun
* hello tom jim cat gun
* offset line --> 0 hello tom jim cat gun
* offset line --> 30 hello tom jim cat gun
* KeyIn Long -->LongWritable
* ValueIn String-->Text
* KeyOut String-->Text
* ValueOut Integer-->IntWritable
*
*/
public class WordCountMapper extends Mapper<LongWritable, Text,Text , IntWritable>{
/**
* 一行执行一次
* 100
* 参数一 输入key 数据的偏移量
* 参数二 输入value 行数据
* @param key
* @param value
* @param context
* @throws IOException
* @throws InterruptedException
*/
@Override
protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
String[] ws = value.toString().split("\\s+");
for (String word : ws) {
// 单词 1 单词 1
context.write(new Text(word),new IntWritable(1));
}
}
}
将数据写出到缓冲区中---->分区 排序 分组---> Reducer
2.3 ReduceTask类
Reducer接收缓冲区中数据 进行每组处理
继承Reducer类 , 重写里面的reduce方法
-
reduce(Text key, Iterable<IntWritable> values, Context context)
一组key执行一次 (一个单词执行一次)
参数一 key[组名] 单词a
参数二 a对应的多个1 存储在迭代器 <1,1,1,1,1,1,1>
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;
import java.io.IOException;
/**
* @Auther: 多易教育-行哥
* @Date: 2020/7/9
* @Description:
*/
public class WordCountReducer extends Reducer<Text, IntWritable,Text,IntWritable> {
/**
* 一个单词 一组 执行一次
* b
* d 两组
* 执行两次
* 单词 b <1,1,1,1,1,1,1,1,1>
* @param key
* @param values
* @param context
* @throws IOException
* @throws InterruptedException
*/
@Override
protected void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
int number = 0 ;
for (IntWritable value : values) { //
number++ ;
}
context.write(key ,new IntWritable(number));
}
}
2.4 启动类
package com._51doit.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;
/**
* @Auther: 多易教育-行哥
* @Date: 2020/7/10
* @Description:
*/
public class WorldCountDriver {
public static void main(String[] args) throws Exception {
// 1 配置对象
Configuration conf = new Configuration();
// 2 创建任务对象
Job job = Job.getInstance(conf, "wc");
// 2.1 设置 map和reduce任务类
job.setMapperClass(WordCountMapper.class);
job.setReducerClass(WordCountReducer.class);
//2.2 设置map和reduce 的输出KV
job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(IntWritable.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(IntWritable.class);
// 2.3 设置reduce的个数 默认1
job.setNumReduceTasks(2);
// 2.3 设置输入和输出路径
FileInputFormat.setInputPaths(job,new Path("d://wc/"));
FileOutputFormat.setOutputPath(job,new Path("d://wc/res/"));
// 3 提交任务 等待程序执行完毕 返回值是否成功
boolean b = job.waitForCompletion(true);
System.exit(b?0:-1);
}
}