一、MapReduce概述
1. 定义
MapReduce是一个分布式运算程序的编程框架。
2. 优势劣势
优点:
- 易于编程:用户只需关心业务逻辑。实现框架的接口。
- 良好的扩展性:可以动态增加服务器,解决计算资源不够问题。
- 高容错性:任何一台机器挂掉,可以将任务转移到其他节点。
- 室和海量数据计算(TB/PB)。几千台服务器同时计算。
缺点: - 不擅长实时计算。 (mysql)
- 不擅长流式计算。(sparktreaming flink)
- 不擅长DAG有向无环图计算。(spark)
3. 核心编程思想
- MapReduce运算程序一般分为map阶段和reduce阶段。
- map阶段的并发maptask,完全并发运行,互不相干。
- reduce阶段的并发reducetask,完全互不相干,但是他们的数据依赖于上一阶段的所有maptask并发实例的输出。
4.MapReduce编程规范
- mapper阶段
- 用户自定义的mapper要继承父类
- mapper的输入数据是kv对的形式(kv的类型可自定义)
- mapper中的业务逻辑写在map()方法中
- mapper的输出数据是kv对的形式(kv的类型可自定义)
- maptask进程对每一个<k,v>只调用一次
- reducer阶段
- 用户自定义的reducer要继承父类
- mapper的输入数据是mapper的输出数据类型
- reducer中的业务逻辑写在reduce()方法中
- reducetask进程对每一组相同k的<k,v>组调用一次reducetask进程。
- driver阶段
相当于yarn集群的客户端,用于提交整个进程到yarn集群。
5. Wordcount案例
pom.xml配置:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.itcast</groupId>
<artifactId>day05_mapreduce</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-client</artifactId>
<version>2.7.7</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-common</artifactId>
<version>2.7.7</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-hdfs</artifactId>
<version>2.7.7</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>RELEASE</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-mapreduce-client-core</artifactId>
<version>2.7.7</version>
</dependency>
</dependencies>
</project>
mapper:
package cn.itcast.mapreduce;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;
import java.io.IOException;
/*
四个泛型解释:
KEYIN:K1的类型
VALUEIN:V1的类型
KEYOUT:K2的类型
VALUEOUT:V2的类型
*/
public class WordCountMapper extends Mapper<LongWritable, Text,Text,LongWritable> {
//map方法:将K1 V1转化为K2 V2
/*
参数:
key:K1 行偏移量
value:V1 每一行的文本数据
context:表示上下文对象
*/
/*
如何将K1 V1 转化为 K2 V2
*/
@Override
protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
Text text = new Text();
LongWritable longWritable = new LongWritable();
//1.将一行的文本数据进行拆分 (拿到一行数据转换为string,将这一行切分出各个单词)
String[] spilt = value.toString().split(",");
//2.遍历数组,组装K2 V2 (遍历数组,输出<单词,1>)
for (String word : spilt) {
//3.将K2 V2写入上下文
text.set(word);
longWritable.set(1);
context.write(text,longWritable);
}
//将单词作为key,次数1作为value。
}
}
reducer:
package cn.itcast.mapreduce;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;
import java.io.IOException;
/*
四个泛型解释:
KEYIN:K2的类型
VALUEIN:V2的类型
KEYOUT:K3的类型
VALUEOUT:V3的类型
*/
public class WordCountReducer extends Reducer <Text, LongWritable,Text,LongWritable>{
//reduce方法作用:将新的K2 V2转化为K3 V3,将K3 V3写入上下文中
/*
参数:
key:新K2
value:集合 新V2
context:表示上下文对象
*/
@Override
protected void reduce(Text key, Iterable<LongWritable> values, Context context) throws IOException, InterruptedException {
long count = 0;
//1.遍历集合,将集合中的数字相加。、,得到V3
for (LongWritable value : values) {
count += value.get();
}
//2.将K3 V3写入上下文中
context.write(key,new LongWritable(count));
}
}
测试:
package cn.itcast.mapreduce;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.conf.Configured;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.TextInputFormat;
import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;
import org.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner;
import javax.xml.soap.Text;
public class JobMain extends Configured implements Tool {
//该方法用于指定一个job任务
public int run(String[] strings) throws Exception {
//1.创建一个job任务对象
Job job = Job.getInstance(super.getConf(),"wordcount");
//如果打包运行出错,则需要加该配置
//job.setJarByClass(JobMain.class);
//2.配置job任务对象(八个步骤)
//一、制定文件的读取方式和读取路径
job.setInputFormatClass(TextInputFormat.class);
TextInputFormat.addInputPath(job,new Path("hdfs://haoopdm:8020/wordcount"));
//指定Map阶段的处理方法和数据类型
job.setMapperClass(WordCountMapper.class);
//设置Map阶段k2的类型
job.setMapOutputKeyClass(Text.class);
//设置Map阶段v2的类型
job.setMapOutputValueClass(LongWritable.class);
//3、4、5、6 采用默认方式
//7.指定reduce阶段的处理方法和数据类型
job.setReducerClass(WordCountReducer.class);
//设置reduce阶段k3的类型
job.setMapOutputKeyClass(Text.class);
//设置reduce阶段v3的类型
job.setMapOutputValueClass(LongWritable.class);
//8.设置输出类型
job.setOutputFormatClass(TextOutputFormat.class);
//设置输出的路径 (不能提前存在)
TextOutputFormat.setOutputPath(job,new Path("hdfs://haoopdm:8020/wordcount_out"));
//等待任务结束
boolean b1 = job.waitForCompletion(true);
return b1?0:1;
}
public static void main(String[] args) throws Exception {
Configuration configuration = new Configuration(); //配置信息
//启动job任务
int run = ToolRunner.run(configuration,new JobMain(),args);
System.exit(run);
}
}
运行模式:
- 集群运行模式:
将MapReduce程序交给yarn集群,分发给多个节点并行运行。
处理的数据和输出的结果应位于hdfs文件系统。
提交集群的实现步骤:
hadoop jar day05_mapreduce-1.0-SNAPSHOT.jar cn.itcast.mapreduce.JobMain
- 本地运行模式:
MapReduce程序是在本地以单进程的形式运行。
处理的数据和输出的结果在本地文件系统。
二、序列化
常用数据序列化类型
三、核心框架原理
- 输入的数据InputFormat
- Shuffle
- 输入的数据OutputFormat
- join
- ETL
- 总结
四、压缩
- 有哪些压缩算法
- 特点
- 在生产环境怎么用