Hadoop中MapReduce概述

news2024/9/24 23:23:16

MapReduce概述

      • MapReduce定义
      • MapReduce优缺点
      • MapReduce核心思想
      • MapReduce进程
      • MapReduce编程规范
      • MapTask并行度决定机制
      • ReduceTask并行度决定机制
      • mapreduce中job的提交流程
      • MapReduce工作流程
      • shuffle机制
      • 分区partition
      • 数据清洗(ETL)
      • 进一步分析MapTask和ReduceTask工作机制
        • MapTask工作机制
        • ReduceTask工作机制
      • 数据压缩

MapReduce定义

MapReduce是一个分布式运算程序的编程框架,是用户开发“基于Hadoop的数据分析应用”的核心框架。

MapReduce核心功能是将用户编写的业务逻辑代码和自带默认组件整合成一个完整的分布式运算程序,并发运行在一个Hadoop集群上。

MapReduce优缺点

优点
1)MapReduce易于编程

它简单的实现一些接口,就可以完成一个分布式程序,这个分布式程序可以分布到大量廉价的PC机器上运行。也就是说你写一个分布式程序,跟写一个简单的串行程序是一模一样的。就是因为这个特点使得MapReduce编程变得非常流行。

2)良好的扩展性

当你的计算资源不能得到满足的时候,你可以通过简单的增加机器来扩展它的计算能力。

3)高容错性

MapReduce设计的初衷就是使程序能够部署在廉价的PC机器上,这就要求它具有很高的容错性。比如其中一台机器挂了,它可以把上面的计算任务转移到另外一个节点上运行,不至于这个任务运行失败,而且这个过程不需要人工参与,而完全是由Hadoop内部完成的。

4)适合PB级以上海量数据的离线处理

可以实现上千台服务器集群并发工作,提供数据处理能力。

缺点
1)不擅长实时计算

MapReduce无法像MySQL一样,在毫秒或者秒级内返回结果。

2)不擅长流式计算

流式计算的输入数据是动态的,而MapReduce的输入数据集是静态的,不能动态变化。这是因为MapReduce自身的设计特点决定了数据源必须是静态的。

3)不擅长DAG(有向无环图)计算

多个应用程序存在依赖关系,后一个应用程序的输入为前一个的输出。在这种情况下,MapReduce并不是不能做,而是使用后,每个MapReduce作业的输出结果都会写入到磁盘,会造成大量的磁盘IO,导致性能非常的低下。

MapReduce核心思想

在这里插入图片描述
(1)分布式的运算程序往往需要分成至少2个阶段。

(2)第一个阶段的MapTask并发实例,完全并行运行,互不相干。

(3)第二个阶段的ReduceTask并发实例互不相干,但是他们的数据依赖于上一个阶段的所有MapTask并发实例的输出。

(4)MapReduce编程模型只能包含一个Map阶段和一个Reduce阶段,如果用户的业务逻辑非常复杂,那就只能多个MapReduce程序,串行运行。

MapReduce进程

一个完整的MapReduce程序在分布式运行时有三类实例进程:

(1)MrAppMaster:负责整个程序的过程调度及状态协调。

(2)MapTask:负责Map阶段的整个数据处理流程。

(3)ReduceTask:负责Reduce阶段的整个数据处理流程。

MapReduce编程规范

用户编写的程序分成三个部分:Mapper、Reducer和Driver。

1.Mapper阶段

(1)用户自定义的Mapper要继承自己的父类

(2)Mapper的输入数据是KV对的形式(KV的类型可自定义)

(3)Mapper中的业务逻辑写在map()方法中

(4)Mapper的输出数据是KV对的形式(KV的类型可自定义)

(5)map()方法(MapTask进程)对每一个<K,V>调用一次

2.Reducer阶段

(1)用户自定义的Reducer要继承自己的父类

(2)Reducer的输入数据类型对应Mapper的输出数据类型,也是KV

(3)Reducer的业务逻辑写在reduce()方法中

(4)ReduceTask进程对每一组相同k的<k,v>组调用一次reduce()方法

3.Driver阶段

相当于YARN集群的客户端,用于提交我们整个程序到YARN集群,提交的是封装了MapReduce程序相关运行参数的job对象

MapTask并行度决定机制

数据块:Block是HDFS物理上把数据分成一块一块。数据块是HDFS存储数据单位。

数据切片:数据切片只是在逻辑上对输入进行分片,并不会在磁盘上将其切分成片进行存储。数据切片是MapReduce程序计算输入数据的单位,一个切片会对应启动一个MapTask。
在这里插入图片描述

ReduceTask并行度决定机制

ReduceTask的并行度同样影响整个Job的执行并发度和执行效率,但与MapTask的并发数由切片数决定不同,ReduceTask数量的决定是可以直接手动设置:

// 默认值是1,手动设置为4
job.setNumReduceTasks(4);

(1)ReduceTask=0,表示没有Reduce阶段,输出文件个数和Map个数一致。

(2)ReduceTask默认值就是1,所以输出文件个数为一个。

(3)如果数据分布不均匀,就有可能在Reduce阶段产生数据倾斜

(4)ReduceTask数量并不是任意设置,还要考虑业务逻辑需求,有些情况下,需要计算全局汇总结果,就只能有1个ReduceTask。

(5)具体多少个ReduceTask,需要根据集群性能而定。

mapreduce中job的提交流程

mapreduce中job提交流程

其中切片的过程是调用input.getSplits(job),这里的input是FileInputFormat对象,实现流程如下:
(1)程序先找到你数据存储的目录。

(2)开始遍历处理(规划切片)目录下的每一个文件

(3)遍历第一个文件ss.txt

a)获取文件大小fs.sizeOf(ss.txt)
b)计算切片大小
computeSplitSize(Math.max(minSize,Math.min(maxSize,blocksize)))=blocksize=128M
c)默认情况下,切片大小=blocksize
d)开始切,形成第1个切片:ss.txt—0:128M 第2个切片ss.txt—128:256M 第3个切片ss.txt—256M:300M(每次切片时,都要判断切完剩下的部分是否大于块的1.1倍,不大于1.1倍就划分一块切片)
e)将切片信息写到一个切片规划文件中
f)整个切片的核心过程在getSplit()方法中完成
g)InputSplit只记录了切片的元数据信息,比如起始位置、长度以及所在的节点列表等。
(4)提交切片规划文件到YARN上,YARN上的MrAppMaster就可以根据切片规划文件计算开启MapTask个数。

切片机制

(1)简单地按照文件的内容长度进行切片

(2)切片大小,默认等于Block大小

(3)切片时不考虑数据集整体,而是逐个针对每一个文件单独切片

MapReduce工作流程

在这里插入图片描述
在这里插入图片描述
上面的流程是整个MapReduce最全工作流程,但是Shuffle过程只是从第7步开始到第16步结束,具体Shuffle过程详解,如下:

(1)MapTask收集我们的map()方法输出的kv对,放到内存缓冲区中

(2)从内存缓冲区不断溢出本地磁盘文件,可能会溢出多个文件

(3)多个溢出文件会被合并成大的溢出文件

(4)在溢出过程及合并的过程中,都要调用Partitioner进行分区和针对key进行排序

(5)ReduceTask根据自己的分区号,去各个MapTask机器上取相应的结果分区数据

(6)ReduceTask会抓取到同一个分区的来自不同MapTask的结果文件,ReduceTask会将这些文件再进行合并(归并排序)

(7)合并成大文件后,Shuffle的过程也就结束了,后面进入ReduceTask的逻辑运算过程(从文件中取出一个一个的键值对Group,调用用户自定义的reduce()方法)

注意:
(1)Shuffle中的缓冲区大小会影响到MapReduce程序的执行效率,原则上说,缓冲区越大,磁盘io的次数越少,执行速度就越快。
(2)缓冲区的大小可以通过参数调整,参数:mapreduce.task.io.sort.mb默认100M。

shuffle机制

在这里插入图片描述
mapreduce shuffle机制原理详解

分区partition

要求将统计结果按照条件输出到不同文件中(分区)。比如:将统计结果按照手机归属地不同省份输出到不同文件中(分区)

默认分区方式是根据key的hashCode对ReduceTasks个数取模得到的。用户没法控制哪个key存储到哪个分区。

即默认分区数量等于reducetask数量。
如果要自定义分区,需要继承 Partitioner<Text, FlowBean> ,然后重写int getPartition(Text key, FlowBean value, int numPartitions)方法,在该方法内可以决定怎么分区,分区数量等。

分区数和ReduceTask的关系:
(1)如果ReduceTask的数量 > getPartition的结果数,则会多产生几个空的输出文件part-r-000xx;

(2)如果1 < ReduceTask的数量 < getPartition的结果数,则有一部分分区数据无处安放,会Exception;

(3)如果ReduceTask的数量 = 1,则不管MapTask端输出多少个分区文件,最终结果都交给这一个ReduceTask,最终也就只会产生一个结果文件 part-r-00000;

(4)分区号必须从零开始,逐一累加。

如果分区数不是1,但是ReduceTask为1,不执行分区过程。因为在MapTask的源码中,执行分区的前提是先判断ReduceNum个数是否大于1。不大于1肯定不执行。

数据清洗(ETL)

“ETL,是英文Extract-Transform-Load的缩写,用来描述将数据从来源端经过抽取(Extract)、转换(Transform)、加载(Load)至目的端的过程。ETL一词较常用在数据仓库,但其对象并不限于数据仓库

在运行核心业务MapReduce程序之前,往往要先对数据进行清洗,清理掉不符合用户要求的数据。清理的过程往往只需要运行Mapper程序,不需要运行Reduce程序。

进一步分析MapTask和ReduceTask工作机制

MapTask工作机制

在这里插入图片描述
(1)Read阶段:MapTask通过InputFormat获得的RecordReader,从输入InputSplit中解析出一个个key/value。

(2)Map阶段:该节点主要是将解析出的key/value交给用户编写map()函数处理,并产生一系列新的key/value。

(3)Collect收集阶段:在用户编写map()函数中,当数据处理完成后,一般会调用OutputCollector.collect()输出结果。在该函数内部,它会将生成的key/value分区(调用Partitioner),并写入一个环形内存缓冲区中。

(4)Spill阶段:即“溢写”,当环形缓冲区满后,MapReduce会将数据写到本地磁盘上,生成一个临时文件。需要注意的是,将数据写入本地磁盘之前,先要对数据进行一次本地排序,并在必要时对数据进行合并、压缩等操作。

溢写阶段详情:

步骤1:利用快速排序算法对缓存区内的数据进行排序,排序方式是,先按照分区编号Partition进行排序,然后按照key进行排序。这样,经过排序后,数据以分区为单位聚集在一起,且同一分区内所有数据按照key有序。

步骤2:按照分区编号由小到大依次将每个分区中的数据写入任务工作目录下的临时文件output/spillN.out(N表示当前溢写次数)中。如果用户设置了Combiner,则写入文件之前,对每个分区中的数据进行一次聚集操作。

步骤3:将分区数据的元信息写到内存索引数据结构SpillRecord中,其中每个分区的元信息包括在临时文件中的偏移量、压缩前数据大小和压缩后数据大小。如果当前内存索引大小超过1MB,则将内存索引写到文件output/spillN.out.index中。

(5)Merge阶段:当所有数据处理完成后,MapTask对所有临时文件进行一次合并,以确保最终只会生成一个数据文件。

当所有数据处理完后,MapTask会将所有临时文件合并成一个大文件,并保存到文件output/file.out中,同时生成相应的索引文件output/file.out.index。

在进行文件合并过程中,MapTask以分区为单位进行合并。对于某个分区,它将采用多轮递归合并的方式。每轮合并mapreduce.task.io.sort.factor(默认10)个文件,并将产生的文件重新加入待合并列表中,对文件排序后,重复以上过程,直到最终得到一个大文件。

让每个MapTask最终只生成一个数据文件,可避免同时打开大量文件和同时读取大量小文件产生的随机读取带来的开销。

ReduceTask工作机制

在这里插入图片描述
(1)Copy阶段:ReduceTask从各个MapTask上远程拷贝一片数据,并针对某一片数据,如果其大小超过一定阈值,则写到磁盘上,否则直接放到内存中。

(2)Sort阶段:在远程拷贝数据的同时,ReduceTask启动了两个后台线程对内存和磁盘上的文件进行合并,以防止内存使用过多或磁盘上文件过多。按照MapReduce语义,用户编写reduce()函数输入数据是按key进行聚集的一组数据。为了将key相同的数据聚在一起,Hadoop采用了基于排序的策略。由于各个MapTask已经实现对自己的处理结果进行了局部排序,因此,ReduceTask只需对所有数据进行一次归并排序即可。

(3)Reduce阶段:reduce()函数将计算结果写到HDFS上。

数据压缩

mapreduce中涉及输入输出,合理采用压缩能够提高io效率,并且也能减少磁盘存储空间。
在mapreduce中采用压缩的环节及作用如下:
在这里插入图片描述

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

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

相关文章

项目经理如何制定工作计划?做到这3点就够了

工作计划的重要性在于明确目标和实现具体步骤&#xff0c;协调大家一致行动&#xff0c;增强工作的主动性&#xff0c;减少工作的盲目性&#xff0c;让工作有条不紊地进行。同时&#xff0c;制定计划也可以对工作进度和质量有个保证和标准&#xff0c;对大家的工作有约束和督促…

Android Native crash问题分析

1、准备材料 android-ndk-r21b工具&#xff1a;addr2line和objdump工具。 .so库&#xff1a;crash对应的带符号表的共享库 源代码code&#xff1a;crash对应的源码文件 tombstone&#xff1a;Android系统产生的墓碑文件 2、 tombstone墓碑文件分析 关键信息&#xff1a; c…

前端div水平居中的几种实现方式

借助display布局 父元素开启display:flex布局,并设置justify-content:center主轴的空隙分布 因为是单行,所以使用align-items:center设置侧轴上的对其方式 <body><style>.a{width: 200px;height: 200px;background-color: red;display: flex;justify-content: c…

JS新标签页打开,让你的网站访问更加便捷

前言 大家在浏览网页时&#xff0c;常常需要在新的标签页中打开链接&#xff0c;以便在不离开当前页面的情况下查看其他内容。其中&#xff0c;JS 打开新标签页作为一种常用的功能之一&#xff0c;既可以方便用户快速访问相关链接&#xff0c;又能有效提升网站的用户体验。在本…

【Python 二进制和十六进制】零基础也能轻松掌握的学习路线与参考资料

1.了解二进制和十六进制的基本概念和用途 在计算机中&#xff0c;二进制和十六进制是两种常用的表示数据的方式。二进制只有两个数字0和1&#xff0c;表示一个比特&#xff08;bit&#xff09;&#xff0c;在实际的计算机程序中&#xff0c;常用八个比特表示一个字节&#xff…

如何在 JavaScript 中创建自定义警告框

本文将介绍如何使用 jQuery UI、SweetAlert2 和自定义警报功能在 JavaScript 中创建自定义警报框。 使用 jQuery UI 创建自定义警告框 我们可以使用 jQuery UI 来模仿 JavaScript 本机 alert() 函数的功能。 尽管 jQuery UI 有很多 API&#xff0c;您可以使用它的 dialog() AP…

Python--注释

Python--注释 <font size4, colorblue> 一、Python中注释的形式<font size4, colorblue> 1、单行注释&#xff1a;使用“#”符号注释<font size4, colorblue> 2、多行注释&#xff1a;使用一对三个英文单引号注释<font size4, colorblue> 3、多行注释&…

W3电力线载波通信技术

CK_Label_W3 CK_Label_W3&#xff08;外接供电版&#xff09; 产品型号 CK_Label_W3 尺寸 114.5*44.5*19mm 屏幕尺寸 2.9 inch 分辨率 296*128 像素密度 112dpi 显示技术 电子墨水屏显示 显示颜色 黑/白 外观颜色 白色 按键 4 指示灯 4 RGB灯 灯光颜色…

帮你梳理了一份前端知识架构图

列一份前端知识架构图 在上一篇文章中&#xff0c;我们简要地总结了前端的学习路径与方法&#xff0c;我们提到的第一个学习方法就是&#xff1a;建立知识框架。那么&#xff0c;今天我们就一起来列一份前端的知识框架图。 在开始列框架之前&#xff0c;我想先来谈谈我们的目…

GoogleTest之gMock:创建Mock

目录 MOCK_METHODmock方法的访问属性mock重载函数mock模板类mock非虚函数mock自由函数Nice/Strict/Naggymock方法简化参数mock具体类的替代方法代理给fake mock是用来模拟对象&#xff0c;隔离边界的一种测试方法&#xff0c;以便在开发阶段不需要依赖第三方或其他依赖项可以进…

C#,码海拾贝(31)——约化“对称矩阵“为“对称三对角阵“的“豪斯荷尔德Householder变换法“之C#源代码

using System; namespace Zhou.CSharp.Algorithm { /// <summary> /// 矩阵类 /// 作者&#xff1a;周长发 /// 改进&#xff1a;深度混淆 /// https://blog.csdn.net/beijinghorn /// </summary> public partial class Matrix {…

运维小白必学篇之基础篇第九集:Linux文件管理实验

Linux文件管理实验 实验作业&#xff1a; 1、筛选/etc/issue文件中的空行 2、筛选/etc/passwd文件中以“bash”结尾的行 3、筛选/etc/passwd文件中以“sync”开头的行 4、列出/etc/passwd文件中包含“dns”的行,并显示行号 5、创建a1-a3.txt3个文件&#xff0c;使用tar命令将这…

基于GD32的定时器不完全详解--定时、级联

SysTick 定时器 SysTick 是一个 24 位的倒计数定时器&#xff0c;当计到 0 时&#xff0c;将从 RELOAD 寄存器中自动重装载定时初值。只要不把它在 SysTick 控制及状态寄存器中的使能位清除&#xff0c; 就永不停息。 该定时器的介绍在MCU的手册中一般不会介绍&#xff0c;因为…

MySQL server安装记录

1 安装Notepad 运行下载的 npp.7.9.Installer.x64.exe 2 安装MySQL 将mysql-8.0.22-winx64.zip解压缩&#xff0c;我将其放置D盘根目录下。 进入文件夹&#xff0c;在目录中新建文件夹data和文件my.ini 用NotePad打开my.ini&#xff0c;输入以下内容并保存&#xff0c;其中目…

讨论和总结 树模型 的三种序列化 方式的区别(模型存储大小、序列化所用内存、序列化速度)...

一、前言 本文总结常用树模型&#xff1a; rf&#xff0c;xgboost&#xff0c;catboost和lightgbm等模型的保存和加载&#xff08;序列化和反序列化&#xff09;的多种方式&#xff0c;并对多种方式从运行内存的使用和存储大小做对比 二、模型 2.1 安装环境 pip install xgboos…

「车型分析」移动机器人控制系统典型应用车型 ——叉式移动机器人(AGV/AMR)

叉式移动机器人&#xff08;AGV/AMR&#xff09;是一种常见的移动机器人类型&#xff0c;它摆脱传统的人车操作&#xff0c;自动导航行驶&#xff0c;具有强大的柔性和智能性。叉式移动机器人&#xff08;AGV/AMR&#xff09;不同于传统叉车&#xff0c;它无需人工驾驶运行。具…

Spring纯注解开发模式让开发简化更简化

目录 一.注解开发二.注解定义Bean三.衍生注解四.纯注解开发模式五.注解实现注入 1.自动装配2.按名称注入3.简单数据注入4.读取properties配置文件六.Spring整合MyBatis 一.注解开发 以前跟老韩学习SE时他就说&#xff1a; 注解本质是一个继承了Annotation 的特殊接口,其具体…

龙华商业中心片区旧改:总建面161万平,分5个片区进行建设。

龙华商业旧改&#xff1a;总建面约161万平分5个片区进行建设 据了解&#xff0c;整个龙华商业旧改整体包含北、中、东、南一、南二五个片区&#xff0c;各个片区均整体实施。 更新单元南一片区项目&#xff08;金地宸峯府&#xff09;&#xff0c;拆除用地面积30836.8平方米&…

前4月同比增长超50%,这条座舱智能化赛道国产化率逼近50%

车市行情的低迷&#xff0c;并没有影响智能化人机交互功能的需求增长。 根据高工智能汽车研究院监测数据显示&#xff0c;2023年1-4月中国市场&#xff08;不含进出口&#xff09;乘用车标配HUD&#xff08;W/AR&#xff09;搭载交付55.36万辆&#xff0c;同比增长54.98%&…

附录2-小程序常用API

API有三大类&#xff0c;事件监听API&#xff0c;同步API&#xff0c;异步API 事件监听API都以on开头&#xff0c;比如wx.onWindowResize()监听窗口尺寸变化事件 同步API都以Sync结尾&#xff0c;同步API可以通过函数返回值直接获取&#xff0c;执行出错会抛出异常。比如 wx.…