一、Mapreduce简介
Mapreduce是一个分布式的运算编程框架,核心功能是将用户编写的核心逻辑代码分布式地运行在一个集群的很多服务器上。
MapReduce进程:
一个完整的mapreduce程序在分式运行时有三类实例进程:
① MrAppMaster:负责整个程序的过程调度以及状态协调
②MapTask:负责Map阶段的整个数据处理流程
③ReduceTask:负责Reduce阶段的整个数据处理流程
框架逻辑:
① map端输入:maptask按行读取hdfs数据,并对其进行分片(默认为128M),分发给各个maptask
② map端输出:数据经过map端逻辑处理后,最终输出方式为<key,value>对
③ shuffle:接收从map端传来的hash值,按key进行分发,相同的key分发给同一个reduce
④ reduce:
⑤ 我们主要写的是map端逻辑与reduce端逻辑
数据类型
hadoop内部传输使用的数据类型是Hadoop自身封装的序列化类型。
常用的数据类型对应的Hadoop数据序列化类型表如下:
Java类型 | Hadoop Writable类型 |
---|---|
boolean | BooleanWritable |
byte | ByteWritable |
int | IntWritable |
float | FloatWritable |
long | LongWritable |
double | DoubleWritable |
map | MapWritable |
array | ArrayWritable |
NULL | NullWritable |
MapReduce编程规范
用户编写的程序分成三个部分:Mapper、Reducer和Driver。
1、Mapper阶段
1)用户自定义的Mapper类要继承父类Mapper(org.apache.hadoop.mapreduce.Mapper)
2)Mapper的输入数据是KV对的形式(KV的类型可自定义)
3)Mapper中的业务逻辑写在map方法中,需要重写父类的map()方法。
4)Mapper的输出类型是KV对的形式(KV的类型可自定义)
5)map()方法(MapTask进程)对每一个<k,v>调用一次。
2、Reducer阶段
1)用户自定义的Reducer类要继承父类Reducer(org.apache.hadoop.mapreduce.Reducer)
2)Reducer的输入数据类型对应Mapper的输出数据类型,也是KV对
3)Reducer的业务逻辑写在reduce方法中,重写父类的reduce()方法。
4)ReduceTask进程对每一组相同k的<k,v>组调用一次reduce()方法
3、Driver阶段
相当于YARN集群的客户端,用于提交我们整个程序到YARN集群,提交的是封装了MapReduce程序相关运行参数的job对象。
代码实现:(WordCountDemo)
- map端:每读取一行数据,调用一次mapper。
- mapper客户端类需要继承hadoop的Mapper类,并复写其map方法。
/**
* KEYIN:输入KV数据对中的key的类型,默认为数据文本的偏移量,类型为Long
* VALUEIN:输入KV数据对中的value的类型
* KEYOUT:输出KV数据对中的key的类型
* VALUEOUT:输出KV数据对中的value的类型
* PS:数据类型的转变,Long——》LongWritable,String——》Text,integer——》IntWritable等
*
*/
public class WordCountMapper extends Mapper<LongWritable, Text, Text, IntWritable>{
/**
* map方法是提供给map task进程来调用的,map task进程是每读取一行文本来调用一次我们自定义的map方法
* map task在调用map方法时,传递的参数:
* 一行的起始偏移量LongWritable作为key
* 一行的文本内容Text作为value
*/
@Override
protected void map(LongWritable key, Text value, Context context)
throws IOException, InterruptedException {
//具体逻辑实现
String line = value.toString(); //将一行Text内容转变为String类型,便于操作
String