深入理解MapReduce:使用Java编写MapReduce程序【上进小菜猪】

news2024/11/23 19:03:34

📬📬我是上进小菜猪,沈工大软件工程专业,爱好敲代码,持续输出干货。

MapReduce是一种用于处理大规模数据集的并行编程模型。由于其高效性和可扩展性,MapReduce已成为许多大型互联网公司处理大数据的首选方案。在本文中,我们将深入了解MapReduce,并使用Java编写一个简单的MapReduce程序。
在这里插入图片描述

MapReduce的原理

MapReduce由两个主要阶段组成:Map和Reduce。在Map阶段中,数据集被分成若干个小块,每个小块由Map函数处理,输出一系列键值对。在Reduce阶段中,键值对被聚合成一组较小的结果集。下面我们详细讲解每个阶段的原理。

Map阶段

Map阶段的输入是原始数据集。它将输入数据划分成若干个小块,每个小块由Map函数处理。Map函数的输入是键值对,输出也是键值对。在Map函数中,对每个输入键值对进行操作,生成一组中间键值对,这些中间键值对将作为Reduce阶段的输入。

Reduce阶段

Reduce阶段的输入是Map阶段输出的中间键值对集合。Reduce函数对每个键执行聚合操作,并将结果输出到最终结果集。Reduce函数的输出通常是单个键值对,但也可以是多个键值对。

Shuffle阶段

Shuffle阶段在Map和Reduce阶段之间执行。在Map阶段中,每个Map任务都会生成一组中间键值对。在Shuffle阶段中,这些中间键值对将按照键进行排序并分组,以便Reduce任务可以并行处理具有相同键的中间结果。

MapReduce程序实现

下面我们将使用Java编写一个简单的MapReduce程序。这个程序将计算输入文本中每个单词的出现次数。

首先,我们需要编写Map函数。Map函数将输入文本中的每个单词映射为一个键值对,其中键是单词本身,值是1。以下是Map函数的代码:

public static class Map extends Mapper<LongWritable, Text, Text, IntWritable> {
  private final static IntWritable one = new IntWritable(1);
  private Text word = new Text();

  public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
    String line = value.toString();
    StringTokenizer tokenizer = new StringTokenizer(line);
    while (tokenizer.hasMoreTokens()) {
      word.set(tokenizer.nextToken());
      context.write(word, one);
    }
  }
}

接下来,我们编写Reduce函数。Reduce函数将具有相同键的值相加,并将结果作为键值对输出。以下是Reduce函数的代码:

javaCopy codepublic static class Reduce extends Reducer<Text, IntWritable, Text, IntWritable> {
  public void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
    int sum = 0;
    for (IntWritable value : values) {
      sum += value.get();
    }
    context.write(key, new IntWritable(sum));

最后,我们将Map函数和Reduce函数组合起来,并将它们作为MapReduce程序的一部分提交给Hadoop集群。以下是完整的MapReduce程序:

import java.io.IOException;
import java.util.StringTokenizer;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;

public class WordCount {

  public static class Map extends Mapper<LongWritable, Text, Text, IntWritable> {
    private final static IntWritable one = new IntWritable(1);
    private Text word = new Text();

    public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
      String line = value.toString();
      StringTokenizer tokenizer = new StringTokenizer(line);
      while (tokenizer.hasMoreTokens()) {
        word.set(tokenizer.nextToken());
        context.write(word, one);
      }
    }
  }

  public static class Reduce extends Reducer<Text, IntWritable, Text, IntWritable> {
    public void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
      int sum = 0;
      for (IntWritable value : values) {
        sum += value.get();
      }
      context.write(key, new IntWritable(sum));
    }
  }

  public static void main(String[] args) throws Exception {
    Configuration conf = new Configuration();
    Job job = Job.getInstance(conf, "wordcount");
    job.setJarByClass(WordCount.class);
    job.setMapperClass(Map.class);
    job.setCombinerClass(Reduce.class);
    job.setReducerClass(Reduce.class);
    job.setOutputKeyClass(Text.class);
    job.setOutputValueClass(IntWritable.class);
    FileInputFormat.addInputPath(job, new Path(args[0]));
    FileOutputFormat.setOutputPath(job, new Path(args[1]));
    System.exit(job.waitForCompletion(true) ? 0 : 1);
  }

}

在上面的代码中,我们首先定义了Map类和Reduce类,然后在main函数中将它们组合起来,使用Job类将程序提交给Hadoop集群进行处理。我们使用FileInputFormat和FileOutputFormat指定输入和输出路径。

总结

本文介绍了MapReduce的原理和使用Java编写MapReduce程序的方法。MapReduce是一个强大的并行编程模型,可用于处理大规模数据集。如果你正在处理大数据集,那么MapReduce可能是你的首选方案。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/508665.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

隐语v0.8.2版本更新,首次发布TEEU

隐语v0.8.2版本更新&#x1f31f; 应用层 机器学习&#xff1a; - MPC 纵向 LR &#xff08;SSRegression&#xff09;新增 Policy SGD 优化器和 Early Stopping 支持&#xff0c;减少调参成本&#xff0c;加快收敛速度&#xff1b; - WOE 分箱进行了若干优化&#xff0c;性…

HR SaaS市场竞争火热,肯耐珂萨缘何持续领跑? |爱分析调研

摘要&#xff1a; 中国人力资源数字化市场规模快速增长&#xff0c;各路厂商云集&#xff0c;呈现百花齐放的态势。作为人力资源管理一体化云解决方案的龙头服务商&#xff0c;肯耐珂萨坚定执行价值导向的差异化竞争策略&#xff0c;15年引领行业创新&#xff0c;依托行业领先方…

linux下的Qt打包常见原因分析和雷区,获取一键式打包脚本(能避免各种问题)

目录 一. 大致如下常见问题&#xff1a; &#xff08;1&#xff09;找不到程序所依赖的Qt库 version Qt_5 not found (required by &#xff08;2&#xff09;Could not Load the Qt platform plugin "xcb" in "" even though it was found &#xff0…

64/32位Linux系统的地址空间布局对比分析

Ubuntu从17.10开始不再官方支持32位(i386)架构&#xff08;严格的说是从18.04开始的&#xff0c;因为17.10不支持32位的PC版&#xff0c;但是支持32位的SERVER版&#xff0c;但是偶数稳定版确实是从18.04开始的)&#xff0c;只支持64位(amd64)架构&#xff0c;这是因为随着时间…

为什么ChatGPT用强化学习而非监督学习?

为什么ChatGPT非得用强化学习&#xff0c;而不直接用监督学习&#xff1f;原因不是那么显而易见。在上周发布的《John Schulman&#xff1a;通往TruthGPT之路》一文中&#xff0c;OpenAI联合创始人、ChatGPT主要负责人John Schulman分享了OpenAI在人类反馈的强化学习&#xff0…

去阿里面试,面试前20分钟突然要求候选人展示过去的工作方案,候选人拒绝后,竟被取消面试!...

离职时&#xff0c;你会把自己的工作成果拷贝下来留档吗&#xff1f; 一位网友说&#xff1a; 面试阿里&#xff0c;面试前20分钟&#xff0c;面试官突然要求他展示过去的工作成果&#xff0c;因为之前是用公司电脑&#xff0c;离职时把电脑交上去了&#xff0c;没有任何留档&a…

AE(自动编码器)与VAE(变分自动编码器)的区别和联系?

他们各自的概念看以下链接就可以了&#xff1a;https://blog.csdn.net/weixin_43135178/category_11543123.html 这里主要谈一下他们的区别&#xff1f; 先说结论&#xff1a; VAE是AE的升级版&#xff0c;VAE也可以被看作是一种特殊的AEAE主要用于数据的压缩与还原&#xff0…

redisson中的分布式锁解读

概述 Redisson是一个在Redis的基础上实现的Java驻内存数据网格&#xff08;In-Memory Data Grid&#xff09;。它不仅 提供了一系列的分布式的Java常用对象&#xff0c;还提供了许多分布式服务。其中包括(BitSet, Set, Multimap, SortedSet, Map, List, Queue, BlockingQueue,…

【电机应用控制】——FOC基础理论针对无刷电机360°无死角磁场矢量控制

目录 前言 一、FOC简介 1、概述 2、框图详解 二、FOC控制核心—坐标变换 1、CLARKE变换 2、PARK变换&反变换 三、FOC闭环回路 四、SVPWM解析 总结 前言 声明&#xff1a;学习笔记来自正点原子B站教程&#xff0c;根据自己理解进行精简总结&#xff0c;仅供学习…

『python爬虫』16. 多线程与多进程(保姆级图文)

目录 多线程1. 什么是多线程&#xff1f;2. 串行模式3. 多线程3.1 多线程方法写法3.2 多线程方法带参数3.3 多线程类写法 多进程1. 什么是多进程 欢迎关注 『python爬虫』 专栏&#xff0c;持续更新中 欢迎关注 『python爬虫』 专栏&#xff0c;持续更新中 多线程 1. 什么是多…

优化Docker Compose日志输出,加速容器化应用的轻松部署

摘要&#xff1a; 在使用 Docker Compose 部署容器化应用程序时&#xff0c;优化日志输出对于提升效率和管理便利性至关重要。本文将介绍如何优化 Docker Compose 日志输出&#xff0c;以加速容器化应用的轻松部署过程。 优化操作 当我们使用 Docker Compose 部署容器化应用程…

【Queue新技法】用双数组实现一个队列 C++

目录 1 常规的队列构建2 加入一些限制2-1形式化说明 附录0 双数组或双链表实现队列1 单链表与循环缓冲区实现队列3 参考资料 1 常规的队列构建 到火车站办理退票&#xff0c;排队的人构成队列。注意到有两个关键动作&#xff1a; 入队&#xff0c;即自觉站到队伍的末尾。出队&…

一篇文章搞定《ViewPage2离屏加载》

------《ViewPage2离屏加载》 前言离屏加载是什么OffscreenPageLimit设置OffscreenPageLimit表现OffscreenPageLimit值为1OffscreenPageLimit值为3 OffscreenPageLimit值取多大比较合适 前言 这里就不讲ViewPage了&#xff0c;买新不买旧&#xff0c;用新不用旧。 但是会将Vie…

Power BI: 表格显示切片器选中时间之前的数据

例如下面的例子&#xff0c;Year List表和Caleadar表是1对多的关联关系。 Caleadar表&#xff1a; Caleadar VAR StartYear YEAR(NOW())-5 VAR EndYear YEAR(NOW())5 RETURN ADDCOLUMNS (CALENDAR (DATE(StartYear,1,1), DATE(EndYear,12,31)),"Year", YEAR ([…

【设计模式】| 修炼内功 | 23种设计模式——工厂方法模式(含抽象)

设计模式如同织锦之艺术&#xff0c;精心构筑&#xff0c;展示优美。 学习设计模式&#xff0c;犹如追逐清晨的曙光&#xff0c;扉页掀开了人生的新篇章。当你学会设计模式的奥秘&#xff0c;就如同走进了灯火通明的城市&#xff0c;丰富多彩的建筑&#xff0c;让你大开眼界&am…

30个最常用的空间SQL用例

在开始使用空间 SQL 时&#xff0c;至少对我而言&#xff0c;最大的挑战之一是拥有一个快速简便的参考&#xff0c;以将你当前的 GIS 工作流转换为 SQL。 有许多令人惊叹的资源可以扩展这方面的知识&#xff0c;但本指南旨在成为一本真正简单的食谱&#xff0c;以开始将你当前的…

从零开始的强化学习入门学习路线

强化学习是机器学习领域中的一个分支&#xff0c;它是指智能体通过与环境的交互来学习如何采取最佳行动以最大化奖励信号的过程。强化学习在许多领域都有广泛的应用&#xff0c;如游戏、自动驾驶和机器人控制等。如果你对强化学习感兴趣&#xff0c;下面是一个入门强化学习的学…

SequoiaDB分布式数据库2023.4月刊

本月看点速览 赋能产业升级&#xff0c;荣获新睿之星 聚焦金融&#xff0c;进一步探索非结构化数据价值释放 再获肯定&#xff0c;入选2023年中国最佳信创厂商入围名单 青杉计划2023已开启&#xff0c;一起攀登更高的“杉” 赋能产业升级&#xff0c;荣获新睿之星 4月18日…

PyTorch典型函数之gather

PyTorch典型函数之gather 作用描述函数详解典型应用场景(1) 深度强化学习中计算损失函数 参考链接 作用描述 如上图所示&#xff0c;假如我们有一个Tensor A&#xff08;图左&#xff09;&#xff0c;要从A中提取一部分元素组成Tensor B&#xff08;图右&#xff09;&#xff0…

7.外观模式C++用法示例

外观模式 一.外观模式1.原理2.特点3.外观模式与装饰器模式的异同4.应用场景C程序示例 一.外观模式 外观模式&#xff08;Facade Pattern&#xff09;是一种结构型设计模式&#xff0c;它提供了一个简单的接口&#xff0c;隐藏了一个或多个复杂的子系统的复杂性&#xff0c;并使…