深入理解 MapReduce:从概念到实战

目录

一、MapReduce 概述

1、MapReduce 的起源与发展

2、MapReduce 的核心思想

二、MapReduce 实现过程

1、Map 阶段

2、Shuffle 阶段

3、Reduce 阶段

三、案例分析

1、Map 阶段

2、Shuffle 阶段

3、Reduce 阶段

4、Driver 阶段


一、MapReduce 概述

MapReduce 是一种用于大规模数据集并行处理的编程模型,它具有高效、可靠、易于扩展等特点,被广泛应用于大数据处理领域。

MapReduce 是一种用于大规模数据集并行处理的编程模型,它具有高效、可靠、易于扩展等特点,被广泛应用于大数据处理领域。

1、MapReduce 的起源与发展

  • MapReduce 最早由 Google 提出,其诞生源于 Google 面临的大规模数据处理需求。在互联网时代,数据量呈爆炸式增长,传统的数据处理方式已经无法满足需求。Google 为了解决这一问题,开发了 MapReduce 编程模型,以实现高效的大规模数据处理。
  • 随着大数据时代的到来,MapReduce 迅速得到了广泛的关注和应用。许多开源软件项目,如 Hadoop,都实现了 MapReduce 编程模型,使得更多的企业和开发者能够利用这一技术进行大数据处理。
  • 经过多年的发展,MapReduce 已经成为大数据处理的核心技术之一。它不仅在互联网行业得到了广泛应用,还在金融、医疗、科学研究等领域发挥着重要作用。

2、MapReduce 的核心思想

  • 将复杂的计算任务分解为 Map 和 Reduce 两个阶段,这是 MapReduce 的核心设计理念。这种分解方式使得大规模数据处理变得更加简单和高效。
  • 在 Map 阶段,输入数据被分割成多个小的数据集,每个数据集被分配给一个 Map 任务。Map 任务会对输入数据进行处理,将其转换为键值对的形式。通常,键是某个特定的属性,值是与该属性相关的数据。例如,对于文本处理任务,Map 任务可以将每个单词作为键,将单词出现的次数作为值。
  • 在 Reduce 阶段,接收来自 Shuffle 阶段的键值对,对相同键的值进行合并和处理。Reduce 任务会对每个键的值进行聚合操作,例如求和、求平均值等。最终,Reduce 任务会生成输出结果,通常是一个键值对的集合。
  • 通过分布式计算实现高效的数据处理。MapReduce 利用分布式计算的优势,将数据分布在多个节点上进行并行处理。这种方式可以大大提高数据处理的速度和效率,尤其是对于大规模数据集的处理。同时,MapReduce 还具有良好的容错性,即使某个节点出现故障,也不会影响整个作业的执行。

二、MapReduce 实现过程

1、Map 阶段

  • Mapper 的参数
    (1)KEYIN:map 阶段输入的 key 的类型。
    (2)VALUEIN:map 阶段输入的 value 的类型。
    (3)KEYOUT:map 阶段输出的 key 的类型。
    (4)VALUEOUT:map 阶段输出的 value 的类型。
  • map 函数
    (1)重写关键所在。写入具体的业务逻辑,根据输入的键值对进行特定处理,生成新的键值对作为输出。
    (2)使用 context.write (key, value) 完成数据传递,将处理后的键值对输出到下一个阶段(通常是 Shuffle 阶段)。
  • Context
    (1)当前环境的抽象概念,提供对环境相关信息的访问和管理能力。
    (2)如读取输入数据、输出数据、报告进度、获取配置信息等。
    (3)具体如 context.write 将键值对输出到下一个阶段(reduce 阶段)。
  • run 方法
    (1)先执行 setup,再循环(每次执行一遍 map),最后 cleanup。
    (2)setup:在每个 Map 任务开始时执行一次,用于初始化工作,如打开文件、建立数据库连接等。
    (3)循环中执行具体的 map 逻辑,对输入数据进行处理并输出键值对。
    (4)cleanup:当所有输入数据都处理完毕后,调用 cleanup 方法进行清理工作,如关闭文件、断开数据库连接等。

2、Shuffle 阶段

  • 作用与重要性
    (1)负责将 Map 阶段生成的键值对进行重新组合和排序。
    (2)为后续的 Reduce 阶段提供高效的数据处理基础。
  • 具体过程
    (1)根据键进行分区,将相同键的键值对分配到同一个分区中。
    (2)对每个分区中的键值对按照键进行排序。

3、Reduce 阶段

  • Reducer 的参数
    (1)KEYIN:reduce 阶段输入的 key 的类型,与 Mapper 输出的 key 类型相对应。
    (2)VALUEIN:reduce 阶段输入的 value 的类型,通常是一个可迭代的集合,包含了所有具有相同 key 的值。
    (3)KEYOUT:reduce 阶段输出的 key 的类型。
    (4)VALUEOUT:reduce 阶段输出的 value 的类型。
  • reduce 函数
    (1)重写关键所在。接收来自 Shuffle 阶段的键值对,对相同 key 的值进行合并和处理。
    (2)根据具体的业务需求进行聚合操作,如求和、求平均值等。
    (3)使用 context.write (key, value) 输出处理后的键值对。
  • Context
    与 Mapper 中的 Context 类似,用于输出数据、报告进度等操作。
  • run 方法
    (1)先执行 setup,进行一些初始化工作。
    (2)然后对于每个输入的键值对,调用 reduce 函数进行处理。
    (3)最后执行 cleanup,进行清理工作。

4、Driver 阶段

  • 设置作业配置
    (1)设置输入输出路径,指定输入数据的来源和输出结果的存储位置。
    (2)设置 Map 和 Reduce 任务的数量,根据数据规模和集群资源进行合理配置。
    (3)设置其他相关参数,如数据格式、压缩方式等。
  • 启动任务
    (1)创建 Job 对象,用于表示一个 MapReduce 作业。
    (2)设置 Mapper、Reducer、输入输出格式等作业的各个组件。
    (3)提交作业到集群,启动 Map 和 Reduce 任务的执行。
  • 监控任务执行状态
    (1)通过查询作业的状态信息,了解作业的执行进度。
    (2)处理作业失败的情况,进行错误处理和重试。
    (3)确保作业能够顺利完成,或者在出现问题时及时采取措施。

三、案例分析

某中学一次月考后,有一份某年级学生的成绩表,现要求统计本次月考各科目平均成绩,其中部分内容和平均成绩如下所示:

表1:部分学生成绩和全年级最终平均成绩

Sno

Course

Grade

Sno

Course

Grade

Course

Avg_grade

202101

语文

96

202102

语文

109

语文

59

202101

数学

149

202102

数学

118

数学

75

202101

英语

130

202102

英语

141

英语

69

202101

物理

90

202102

物理

78

物理

50

202101

化学

44

202102

化学

99

化学

74

202101

生物

99

202102

生物

70

生物

53

1、Map 阶段

  • 对于输入的CSV文件的每一行,Map 任务根据CSV文件特性是用split方法以“,”形式将其分割成三部分,分别是学号、学科、分数存储到一个col数组里,并生成键值对,其中键是学科,值是 分数。
  • 例如,对于输入的文本行 “202100001,语文,73”,Map 任务会生成键值对:(“语文”, 73) 。
package com.hadoop.mapreduce.averagescore;

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;

public class AvgScoreMap extends Mapper<LongWritable, Text, Text, IntWritable> {
    private Text outkey = new Text();
    private IntWritable outvalue = new IntWritable();

    @Override
    protected void map(LongWritable key, Text value, Mapper<LongWritable, Text, Text, IntWritable>.Context context) throws IOException, InterruptedException {
        String line = value.toString();
        String[] col = line.split(",");
        //202100001	语文	73
        outkey.set(col[1]);
        outvalue.set(Integer.parseInt(col[2]));
        context.write(outkey, outvalue);
    }
}

2、Shuffle 阶段

  • 将 Map 阶段生成的键值对进行重新组合和排序。
  • 相同键的键值对分配到同一个分区中,并按照键进行排序。

3、Reduce 阶段

  • Reduce 任务接收来自 Shuffle 阶段的键值对,对相同键的值进行合并和处理。
  • 对每个学生的同一学科分数求和,生成最终的输出结果。
  • 例如,对于键 “语文”,Reduce 任务会接收多个键值对,如 (“语文”, 73)、(“语文”, 110)、(“语文”, 106) 等,然后将这些值进行求和,并除以总数,得到最终的输出结果 (“语文”, 59)。
package com.hadoop.mapreduce.averagescore;

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

import java.io.IOException;

public class AvgScoreReduce extends Reducer<Text, IntWritable, Text, IntWritable> {
    private IntWritable outvalue = new IntWritable();

    @Override
    protected void reduce(Text key, Iterable<IntWritable> values, Reducer<Text, IntWritable, Text, IntWritable>.Context context) throws IOException, InterruptedException {
        int sum = 0;
        int count = 0;
        int avg = 0;
        for (IntWritable value : values) {
            sum += value.get();
            count++;
        }
        avg = sum / count;
        outvalue.set(avg);
        context.write(key, outvalue);
    }
}

4、Driver 阶段

  • 设置作业的配置参数,如输入输出路径、Map 和 Reduce 任务的数量等。
  • 启动 MapReduce 作业,并监控作业的执行状态,确保作业能够顺利完成。
package com.hadoop.mapreduce.averagescore;

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 AvgScoreDriver {
    public static void main(String[] args) throws IOException, InterruptedException, ClassNotFoundException {
        //1.获取job
        Configuration conf = new Configuration();
        Job job = Job.getInstance(conf);

        //2.设置jar路径
        job.setJarByClass(AvgScoreDriver.class);

        //3.关联mapper和reducer
        job.setMapperClass(AvgScoreMap.class);
        job.setReducerClass(AvgScoreReduce.class);

        //4.设置map输出的key、value类型,前面WordCountMap里的后2个参数Text, IntWritable
        job.setMapOutputKeyClass(Text.class);
        job.setMapOutputValueClass(IntWritable.class);

        //5.设置最终输出的key、value类型,前面WordCountReduce里的后2个参数Text, IntWritable
        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(IntWritable.class);

        //6.设置输入路径和输出路径
        FileInputFormat.setInputPaths(job, new Path("D:\\hsn\\java\\Hadoop\\MapReduce\\averagescore\\input"));//输出文本test.txt所在的windows路径
        FileOutputFormat.setOutputPath(job, new Path("D:\\hsn\\java\\Hadoop\\MapReduce\\averagescore\\output\\output1"));//输出结果所在的windows路径

        //7.提交job
        boolean result = job.waitForCompletion(true);
        System.exit(result ? 0 : 1);
    }
}

查看part-r-00000文件,语数英物化生平均分最终结果截图如下:

图1:案例结果截图

通过这个案例,我们可以看到 MapReduce 如何将一个复杂的计算任务分解为多个简单的阶段,并通过并行处理来提高计算效率。在实际应用中,MapReduce 可以用于处理各种大规模数据集的问题,例如数据分析、机器学习、搜索引擎等。

写在最后,MapReduce 是一种强大的编程模型,它能够帮助我们高效地处理大规模数据集。通过理解 MapReduce 的概念、实现过程以及继承 Mapper、Reducer、Driver 等类的方法,我们可以更好地应用 MapReduce 来解决实际问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值