首页 > 其他 > 详细

Hadoop MapReduce学习小结

时间:2020-03-08 10:29:35      阅读:77      评论:0      收藏:0      [点我收藏+]

一、MapReduce定义

  MapReduce是一个分布式运算程序的编程框架,是基于Hadoop的数据分析计算的核心框架。

  MapReduece处理过程分为两个阶段:Map和Reduce。

  Map复测把一个任务分解成多个任务,

  Reduce负责把分解后多任务处理的结果汇总。

优点:

  1. MapReduce易于编程(它可以简单的实现一些接口,就可以完成一个分布式程序)
  2. 良好的扩展性
  3. 高容错性
  4. 适合PB级以上海量数据的离线处理

缺点:

  1. 不擅长实时计算:MapReduce无法像MySQL一样,在毫秒或者秒级内返回结果
  2. 不擅长流式计算:流式计算的输入数据是动态的,二MapReduce的输入数据集是静态的,不能动态变化。这是因为MapReduce自身的设计特点决定了数据源必须是静止的。
  3. 不擅长DAG(有向图)计算:多个应用程序存在依赖关系,后一个应用程序的输入为前一个的输出。在这种情况下,MapReduce并不是不能做,而是使用后,每个MapReduce作业的输出结果都会写入到磁盘,会造成大量的磁盘IO,导致性能非常的低下。

二、Hadoop序列化

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;

}

 三、MapReduce框架原理

技术分享图片

 

 须了解InputFormat数据输入以及切片机制

Ⅰ .FileInputFormat的实现类 

  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

把切片分解成KVcreateRecordReader

FileInputFormat

按文件->块大小

没有实现

TextInputFormat

继承FileInputFormat

LineRecordReader<偏移量,行数据>

CombineTextIntputFormat

重写了getSplit,小块合并切

CombineFileRecordReader(LineRecordReader处理一样,只不过跨文件了) <偏移量,行数据>

KeyValueTextInputFormat

继承FileInputFormat

KeyValueLineRecordReader<分隔符前,分隔符后 >

NLineInputFormat

重写了getSplit,按行切

LineRecordReader<偏移量,行数据>

自定义

继承FileInputFormat

自定义RecordReader

 

Ⅱ.Shuffle机制

  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是MR程序中Mapper和Reducer之外的一种组件
  • Combiner组件是父类就是Reducer
  • Combiner和Reducer的区别在于运行的位置 Combiner是在每一个MapTask所在的节点运行 Reducer是接收全局所有Mapper的输出结果
  • Combiner的意义就是对于每一个MapTask的输出进行局部汇总,以减少网络传输量。
  • Combiner能够应用的前提是不能影响最终的业务逻辑,而且,Combiner的输出kv应该跟Reducer的输入kv类型要对应起来。

 

自定义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数据输出

  OutputFormat是MapRedue输出的基类,所有实现MapReduce输出都实现了OutputFormat接口。下面我们介绍几种常见的OutputFormat实现类

1、文本输出TextOutputFormat

  默认的输出格式是TextOutputFormat,它把每条记录写为为本行。它的键和值可以是任意类型,因为TextOutputFormat调用toString()方法把他们转换为字符串。

2、SequenceFileOutputFormat

  将SequenceFileOutputFormat输出作为后续MapReduce任务的输入,这便是一种好的输出格式,因为他的格式紧凑,很容易被压缩。

3、自定义OutputFormat

  根据用户需求,自定义实现输出。

 

Hadoop MapReduce学习小结

原文:https://www.cnblogs.com/g-cl/p/12436957.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!