MapReduce学习总结

1.MapReduce是什么?

mapreduce是一个分布式计算编程框架

优点

  1. 易于编程。用户不需要考虑多个节点任务的分配,以及节点之间的沟通。
  2. 高容错性。能够把出现故障的节点的任务转交给其他节点完成。
  3. 高扩展性。可以通过添加节点数量提高,计算能力。
  4. 可以处理海量数据的计算

缺点

  1. 不能够实时处理数据。
  2. 不能够处理流式数据。
  3. 不适合处理有向无环图,就是不适合处理,一个任务的结果是另一个任务的开始条件。

 2.MapReduce的编程思想?

 mapreduce分为map阶段和reduce阶段,map阶段的并发maptask并行运行,互不干扰。

reduce阶段互不干扰,数据依赖于maptask实例的输出。

3.Mapreduce实例wordcount环境准备

1.设置maven依赖

可以在终端,输入 hadoop version查看hadoop的版本。

 2.创建三个类用来实现mapreduce的三部分功能

3.分别创建三个类的内容

Mapper类

package org.example;

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;

//map中有两对键值对参数,根据问题设置参数类型
public class WordCountMapper extends Mapper<LongWritable, Text, Text, IntWritable>{
    private Text text = new Text();
    private   IntWritable outV=new IntWritable(1);
    @Override
    protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {

//        获取一行
        String string = value.toString();
//        对一行数据按照空格切分
        String[] s = string.split(" ");
//        循环写出
        for(String word: s){
            text.set(word);
//            使用context.write写出
            context.write(text,outV);
        }
    }


}

Reduce类

package org.example;

import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;

import java.io.IOException;

public class WordCountReduce extends Reducer<Text,IntWritable,Text,IntWritable> {
    private IntWritable outV=new IntWritable();
    @Override
    protected void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
        int sum=0;
//        统计出现次数
        for(IntWritable val:values){
            sum=sum+val.get();
        }
        outV.set(sum);
//        写出
        context.write(key, outV);
    }
}

Deriver类

package org.example;

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;


import java.io.IOException;

public class WordCountDriver {
    public static void main(String[] args) throws IOException, InterruptedException, ClassNotFoundException {
//        创建job
        Configuration conf = new Configuration();
        Job job = Job.getInstance(conf);
//        添加jar包路径
        job.setJarByClass(WordCountDriver.class);
//        关联mapper和reduce
        job.setMapperClass(WordCountMapper.class);
        job.setReducerClass(WordCountReduce.class);
//        设置map阶段的输出键值对类型
        job.setMapOutputKeyClass(Text.class);
        job.setMapOutputValueClass(IntWritable.class);
//        设置最终的输出类型
        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(IntWritable.class);
//        设置输入路径输出路径
        FileInputFormat.setInputPaths(job, new Path(args[0]));
        FileOutputFormat.setOutputPath(job, new Path(args[1]));
//       提交job
        boolean result = job.waitForCompletion(true);
        System.exit(result ? 0 : 1);
    }
}

4.利用maven打包成jar包

 5.上传jar包

1.使用xftp把jar包放到/usr/local/hadoop目录下

2.要计算单词数目的txt文件上传到hdfs的/input目录

hdfs dfs -put hello.txt /input

3.运行jar包

hadoop jar jar包名称 Deriver类的完整路径  /input  /output

4.在HDFS网页端查看运行结果

进入hadoop网页端:在浏览器地址栏输入

ip地址:50070

如果没有执行程序之前就有output目录,就会报错

//删除output目录

hdfs dfs -rm -r /output

 6.切片与并行度

1.MapTask开启个数就是并行度

2.在HDFS中一个块的大小是128M,是把数据在物理上分成不同的块存储在不同的节点上。

3.分片是在逻辑上对数据进行划分,分片的大小一般是等于块大小,但是用户也可以修改分片的大小。

4.分片大小=块大小,可以减少节点联系其他节点获取块数据

 

 6.2 TextInputFormat

TextInputFormat是FileInputFormat的实现类,按照文件进行切片,按行读取数据,键是字节索引LongWritable类型,值是一行内容Text类型。

6.3 CombineTextInputFormat

是把多个小文件合并成一个切片,有两个过程虚拟存储过程,切片过程

虚拟存储:把输入目录下多个文件的大小和setMaxInputSplitSize进行比较,如果小于则单独形成一个文件,如果大于max且小于2*max则分成两个文件,大于2*max,先按照最大值进行切分,判断剩余大小与max的关系如果大于max小于2*max则对半分。

切片过程:如果大于max则单独形成一个切片,如果小于max则与下一个文件形成一个切片。

7.MapReduce的执行流程

1.对原始数据进行切片,切片个数确定开启多少个maptask

2.向yarn提交job的相关信息(job.split:切片信息,jar包,job的相关参数)。

3.yarn开启Mrappmaster,Mrappmaster通过读取切片信息确定开启多少个maptask。

4.maptask使用InputFormat读取数据,InputFormat读取数据后生成 <k,v>把数据交给map( k,v)方法,map()方法把生成的<k,v>键值对数据,把数据输出到环形缓冲区(默认是100M的内存,一半存储索引,一半存储内存)   数据在环形缓冲区从起点开始向两侧写索引和数据写到80%时(索引+数据占据80M空间)停止写入数据,在环形缓冲区剩余20%的中间开始向两侧反向写数据和索引,同时把占据80M的数据进行溢写 产生多个多个溢写文件

环形缓冲区

 5.数据进入环形缓冲区之后会把数据进行分区,并在分区内部进行排序(当数据到达80%时再进行排序,排序方法是快排 ,对key的索引进行排序,按照字典顺序排)然后进行溢写形成溢写文件

6.溢写会产生多个溢写文件(因为溢写文件的大小是80M,原始数据如果远大于80M,每进行一次溢写就会产生一个溢写文件),根据分区对文件进行归并排序 (对已经有序的文件进行排序)保证每个分区内部有序,放到磁盘上。

7. Mrappmaster在MapTask任务完成后(如果maptask的数量多的话可以先将一部分已经完成的maptask的结果合并交给reducetask)启动reducetask(有多少个分区就开启多少个reducetask),相同分区的数据在同一个reducetask 。

8.然后在对数据合并文件,然后归并排序,最后把数据交给reduce()方法。

9.reduce()方法处理完毕之后使用outputFormat方法写到结果文件

8.Shuffe机制

1.shuffe是从map()之后reduce()方法之前的过程

8.1分区

分区在输出结果目录中就是多个文件。

自定义分区:

1.创建一个类继承partitioner< >类,重写getPartition()方法

2.在job驱动内设置自定义partitioner

job.setPartitionerClass(CustomPartitioner.class)

3.根据partition的个数设置redtask的个数

job.setNumReduceTasks(5)

分区总结:

如果reducetask的个数大于分区个数:会产生几个空文件。

reducetask的个数大于一但小于分区个数:会报错。

reducetask的个数=1,不论有多少个分区都只会形成一个文件。

9.序列化和反序列化

序列化:就是把内存中的对象转换成字节序列 便于存储到磁盘和网络传输。

反序列化:把收到的字节序列转换成内存中的对象。

常用的基本序列化类型无法满足需要,所以需要实现一个对象的序列化

要求是:实现Writable接口,重写序列化和反序列化方法,重写toString()方法。

10.自定义排序

对象作为key进行传输需要,设置自定义排序

1.实现WriteComparable接口

2.重写comparaTo()方法。

comparaTo实现正序排列

public class Person implements Comparable<Person> {
    private int age;

    // 省略構造方法和其他方法

    @Override
    public int compareTo(Person p) {
        return this.age - p.getAge();
    }
}

comparaTo实现倒序排列

public class Person implements Comparable<Person> {
    private int age;

    // 省略構造方法和其他方法

    @Override
    public int compareTo(Person p) {
        // 倒序排列,直接取相反數即可
        return p.getAge() - this.age;
    }
}

自我理解就是:如果comparaTo()如果返回正数,则当前数放到比较数的上面,否则放到比较数的下面。

  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值