MapReduce是一个分布式运算程序的编程框架,是基于Hadoop的数据分析计算的核心框架。
MapReduece处理过程分为两个阶段:Map和Reduce。
Map复测把一个任务分解成多个任务,
Reduce负责把分解后多任务处理的结果汇总。
优点:
缺点:
https://blog.csdn.net/qq_42815754/article/details/82701290
1.什么是序列化?
序列化就是把内存中的对象,转换为字节序列(或其他数据传输协议)以便于存储到磁盘(持久化)和网络传输
2.为什么要序列化?
一般来说,“活的”对象只生存在内存里,换机断电就没有了。而且“活的”对象只能有本地的进程使用,不能不发送到网络的另一台计算机。然而序列化可以存储“活的”对象,可以将“活的”对象发送到远程计算机。
3.Hadoop序列化特点:
4.自定义bean对象实现序列化接口(Writable)
在企业开发中往往常用的基本序列化类型不能满足所有需求,比如在Hadoop框架内部传递一个bean对象,那么该对象就需要实现序列化接口。
具体实现bean对象序列化步骤如下7步。
(1)必须实现Writable接口
(2)反序列化时,需要反射调用空参构造函数,所以必须有空参构造
public FlowBean() { super(); } |
(3)重写序列化方法
@Override public void write(DataOutput out) throws IOException { out.writeLong(upFlow); out.writeLong(downFlow); out.writeLong(sumFlow); } |
(4)重写反序列化方法
@Override public void readFields(DataInput in) throws IOException { upFlow = in.readLong(); downFlow = in.readLong(); sumFlow = in.readLong(); } |
(5)注意反序列化的顺序和序列化的顺序完全一致
(6)要想把结果显示在文件中,需要重写toString(),可用”\t”分开,方便后续用。
(7)如果需要将自定义的bean放在key中传输,则还需要实现Comparable接口,因为MapReduce框中的Shuffle过程要求对key必须能排序。详见后面排序案例。
@Override public int compareTo(FlowBean o) { // 倒序排列,从大到小 return this.sumFlow > o.getSumFlow() ? -1 : 1; } |
须了解InputFormat数据输入以及切片机制
FileInputFormat常见的接口实现类包括:TextInputFormat、KeyValueTextInputFormat、NLineInputFormat、CombineTextInputFormat和自定义InputFormat等。
1.TextInputFormat
TextInputFormat是默认的FileInputFormat实现类。按行读取每条记录。键是存储该行在整个文件中的起始字节偏移量,LongWritable类型。值是这行的内容,不包括任何终止符(换行符和回车符),Text类型。
2.KeyValueTextInputFormat
没一行均为一条记录,被分隔符分割为key、value,可以通过在驱动类中设置conf.set(KeyValueLineRecordReader.KEY_VALUE_SEPERATOR,"\t"),来设定分隔符。默认分隔符是tab(\t)。
3.NLineInputFormat
如果使用NineInputFormat,代表每个玛胖斤称护理的InputSplit不在按Block块去划分,而是安NineInputFormat指定的行数N来划分。即输入文件的总行数/N=切片数,如果不整除,切片数=商+1。
4.CombineTextInputFormat
框架默认的TextInputFormat切片机制是对任务按文件规划切片,不管文件多小,都会是一个单独的切片,都会交给一个MapTask,这样如果有大量小文件,就会产生大量的MapTask,处理效率极其低下。
1)应用场景:
CombineTextInputFormat用于小文件过多的场景,它可以将多个小文件从逻辑上规划到一个切片中,这样,多个小文件就可以交给一个MapTask处理。
2)虚拟存储切片最大值设置
CombineTextInputFormat.setMaxInputSplitSize(job, 4194304);// 4m
3)切片机制
生成切片过程包括:虚拟存储过程和切片过程二部分。
FileInputFormat实现类总结
InputFormat |
切片规则(getSplits) |
把切片分解成KV(createRecordReader) |
FileInputFormat |
按文件->块大小 |
没有实现 |
TextInputFormat |
继承FileInputFormat |
LineRecordReader<偏移量,行数据> |
CombineTextIntputFormat |
重写了getSplit,小块合并切 |
CombineFileRecordReader(和LineRecordReader处理一样,只不过跨文件了) <偏移量,行数据> |
KeyValueTextInputFormat |
继承FileInputFormat |
KeyValueLineRecordReader<分隔符前,分隔符后 > |
NLineInputFormat |
重写了getSplit,按行切 |
LineRecordReader<偏移量,行数据> |
自定义 |
继承FileInputFormat |
自定义RecordReader |
Map方法之后,Reduce方法之前的数据处理过程称之为Shuffle。
1.Partition分区
要求将统计结果按照条件输出到不同文件中(分区)。比如:将统计结果按照手机归属地不同省份输出到不同的文件中(分区)
自定义Partitioner步骤
2.WritatbleComparable排序
排序是MapReduce框架中最重要的操作之一。
MapTask和ReduceTask均会对数据按照key进行排序。该操作属于Hadoop的默认行为。任何应用程序中的数据均会被排序,而不管逻辑上是否需要。
默认排序是按照字典顺序排序,而实现该排序的方法是快速排序。
自定义排序WritableComparable
(1)原理分析
bean对象做为key传输,需要实现WritableComparable接口重写compareTo方法,就可以实现排序。
@Override public int compareTo(FlowBean o) { int result; // 按照总流量大小,倒序排列 if (sumFlow > bean.getSumFlow()) { result = -1; }else if (sumFlow < bean.getSumFlow()) { result = 1; }else { result = 0; } return result; }
3.Combiner合并
自定义Combiner实现步骤
(a)自定义一个Combiner继承Reducer,重写Reduce方法
public class WordcountCombiner extends Reducer<Text, IntWritable, Text, IntWritable>{ IntWritable v = new IntWritable(); @Override protected void reduce(Text key, Iterable<IntWritable> values, Reducer<Text, IntWritable, Text, IntWritable>.Context context) throws IOException, InterruptedException { int sum = 0; // 1 汇总操作 for (IntWritable value : values) { sum += value.get(); } v.set(sum); // 2 写出 context.write(key, v); } }
(b)在Job驱动类中设置:
job.setCombinerClass(WordcountCombiner.class);
OutputFormat是MapRedue输出的基类,所有实现MapReduce输出都实现了OutputFormat接口。下面我们介绍几种常见的OutputFormat实现类
1、文本输出TextOutputFormat
默认的输出格式是TextOutputFormat,它把每条记录写为为本行。它的键和值可以是任意类型,因为TextOutputFormat调用toString()方法把他们转换为字符串。
2、SequenceFileOutputFormat
将SequenceFileOutputFormat输出作为后续MapReduce任务的输入,这便是一种好的输出格式,因为他的格式紧凑,很容易被压缩。
3、自定义OutputFormat
根据用户需求,自定义实现输出。
原文:https://www.cnblogs.com/g-cl/p/12436957.html