hadoop_MapReduce详解

MapReduce秒懂

MapReduce定义

MapReduce是一个分布式运算程序的编程框架

MapReduc优缺点

优点

  1. 易于编程
  2. 良好的扩展性
  3. 高容错性
  4. 适合PB级以上海量数据的离线计算

缺点

  1. 不擅长实时计算
  2. 不擅长流式计算
  3. 不擅长DAG(有向图)计算

MapReduc核心思想

  1. Job(作业) : 一个MapReduce程序称为一个Job,MR程序一般需要分成2个阶段:map阶段和reduce阶段
  2. MRAppMaster:MR任务的主节点,一个Job在运行时,会先启动这个进程,负责Job中执行状态的监控、容错、RM申请资源、提交Task等等
  3. Map是MapReduce程序运行的第一个阶段,MapTask负责是Map阶段程序的计算,在一个MR程序的Map阶段,会启动N个MapTask,每个MapTask是完全并行运行,互不相干
  4. Reduce是MapReduce程序运行的第二个阶段(最后一个阶段),Reduce阶段的目的是将Map阶段,每个MapTask计算后的结果进行合并汇总,数据依赖于上一个阶段的所有MapTask并发实例的输出,ReduceTask也是并行运行,每个ReduceTask最终都会产生一个结果
  5. MapReduce程序只能包含一个Map阶段和一个Reduce阶段,如果用户的业务逻辑非常复杂,那就只能多个MapReduce程序,串行运行

MapReduc工作流程

Map阶段

切片(split)

切片指的是MapReduce框架根据输入数据源的大小和配置参数,将数据源分割成多个较小的数据集合,每个数据集合称为一个切片(Split),每个切片会被分配给一个单独的MapTask进行处理

InputFormat

MR程序必须指定一个输入目录,一个输出目录,InputFormat代表输入目录文件的格式。默认的是普通文件,使用FileInputFormat,如果处理的数据在数据库中,需要使用DBInputFormat

FileInputFormat

用来读取数据,其本身为一个抽象类,继承自 InputFormat 抽象类,针对不同的类型的数据有不同的子类来处理,不同的子类有着不同的切片机制,常见的接口实现类如下:

  • TextInputFormat(默认)

      切片机制:
      	1. 通过计算文件的起始位置、文件的长度以及配置的块大小,简单的按照文件的内容长度进行切片
      	2. 切片大小,默认等于Block大小(blocksize)
      	3. 切片时不考虑数据集整体,而是逐个针对每一个文件单独切片
      	4. 每次切片时,都要判断切完剩下的部分是否大于块的1.1倍,不大于1.1倍就划分为一块切片
    
  • KeyValueTextInputFormat

      按行读取,每一行为一条记录,被分隔符分隔,默认分隔符为'\t'
    
  • NLineInputFormat

      切片机制按照指定的行数N来划分,即输入文件的总行数/N=切片数,不能整除则+1片
    
  • CombineTextInputFormat

      用于小文件过多的场景,它可以将多个小文件从逻辑上规划到一个切片中,这样多个小文件就可以交给一个MapTask处理
      切片机制:
      	包括虚拟存储过程和切片两个部分
      虚拟存储过程:
      	1. 将输入目录下所有文件按照文件名称字典顺序一次读入,记录文件大小,并累加计算所有文件的总长度
      	2. 根据设置的虚拟存储切片最大值,将每个文件划分成一个一个设置的切片值大小的文件
      	3. 当剩余数据大小超过设置的切片值且不大于2倍时,将文件均分成2个虚拟存储块(防止出现太小切片)
      切片过程:
      	1. 判断虚拟存储的文件大小是否大于设置的切片值,大于等于则单独形成一个切片
      	2. 如果不大于则跟下一个虚拟存储文件进行合并,共同形成一个切片
      举例:
      	text1大小2M、text2大小5M、text3大小3M、text4大小6M
      	设置的虚拟存储切片最大值为4M
      	虚拟存储过程:
      		text1:2M < 4M 划分为1块
      		text2:4M < 5M < 2 * 4M 划分为2块,块1:2.5M,块2:2.5M
      		text3:3M < 4M 划分为1块
      		text4:6M < 5M < 2 * 4M 划分为2块,块1:3M,块2:3M
      		最终虚拟存储过程划分的块数为6块,2M、2.5M、2.5M、3M、3M、3M
      	切片过程:
      		没有文件大小是大于4M的,所以俩俩合并共同形成一个切片,最终切片为3块
      		2 + 2.5 = 4.5M
      		2.5 + 3 = 5.5M
      		3 + 3 = 6M
    
  • 自定义InputFormat

FileInputFormat切片机制

  1. 通过计算文件的起始位置、文件的长度以及配置的块大小,简单的按照文件的内容长度进行切片
  2. 切片大小,默认等于Block大小(blocksize)
  3. 切片时不考虑数据集整体,而是逐个针对每一个文件单独切片

FileInputFormat切片流程

  1. 程序先找到你数据存储的目录
  2. 开始遍历处理目录下的每一个文件
  3. 遍历第一个文件,获取文件的大小,计算设置切片的大小(默认是块大小128M),开始切片
  4. 将切片信息写到一个切片规划文件中
  5. 提交切片规划文件到YARN上,YARN的MRAppMaster根据切片规划文件计算开启MapTask个数

读取(RecordReader)

RecordReader负责从输入格式中,读取数据,读取后封装为一组记录(k-v),mapreduce只能处理kv

处理(mapper)

将解析出的key_value交给map()函数处理,并产生一系列新的key_value

收集(collect)

收集线程负责将写出的key-value收集到缓冲区(MapOutPutBuffer)中,每个记录在进入缓冲区时,先调用Partitioner(分区器)为记录计算一个区号

  • 缓冲区默认大小为100M

溢写(spill)

溢写线程会在缓冲区已经收集了80%空间的数据时被唤醒,唤醒后负责将缓冲区收集的数据溢写到磁盘上,生成一个临时文件

溢写流程

  1. 一旦缓冲区满足溢写条件,先对缓冲区的所有数据,进行一次排序,排序方式是先按照分区编号Partition进行排序,然后按照key进行升序排序,排序时,只排索引不移动数据,经过排序后,数据以分区为单位聚集在一起,且同一分区内所有数据按照key有序
  2. 按照分区编号由小到大进行溢写,将每个分区中的数据写入任务工作目录下的临时文件中,溢写多次,生成多个临时文件,如果最后一批数据不满足溢写条件会执行一次flush
  3. 将分区数据的元信息写到内存索引数据结构SpillRecord中,其中每个分区的元信息包括在临时文件中的偏移量、压缩前数据大小和压缩后数据大小

合并(combine)

溢写结束后,MapTask对所有临时文件进行一次合并,以确保最终只会生成一个数据文件。因为后续reduce会读取文件,这样可避免同时读取大量文件产生的开销

合并流程

  1. MapTask以分区为单位进行合并。对于某个分区,它将采用多轮递归合并的方式
  2. 每轮合并10(默认)个文件,并将产生的文件重新加入待合并列表中
  3. 对文件进行排序,重复以上过程,直到最终得到一个大文件,这个文件每个分区中的key-value都是有序的
  4. 最终将数据写入到MapTask磁盘的某个文件中

Reduce阶段

拷贝(copy)

ReduceTask从各个MapTask上远程拷贝数据,每个ReduceTask只负责一个分区,所以只copy不同MapTask上这个分区的数据,针对某一片数据,如果其大小超过一定阈值,则写到磁盘上,否则直接放到内存中

合并(merge)

在远程拷贝数据的同时,ReduceTask启动了两个后台线程对内存和磁盘上的文件进行合并,以防止内存使用过多或磁盘上文件过多

  1. 文件大小超过一定阈值,则放到磁盘上,否则放到内存中
  2. 磁盘上的文件数目达到一定阈值,进行一次合并,生成一个更大的文件
  3. 内存中文件大小或者数目超过一定阈值,进行一次合并后将数据写到磁盘上

排序(sort)

由于数据是从多个MapTask上copy过来的,所以要对所有数据进行一次归并排序,保证在进入reduce之前是排好序的

处理(reducer)

将排好序的数据进行分组,调用reduce()函数处理数据,将计算结果写到文件上

分区概述

分区是在MapTask中通过Partitioner来计算分区号

  1. 总的partitions(分区数),取决于用户设置的reduceTask的数量
  2. partitions>1,默认尝试获取用户设置的分区数,如果用户没有定义,那么会使用HashPartitioner,HashPartitioner根据key的hashcode进行计算,相同的key以及hash值相同的key会分到一个区
  3. partitions<=1,默认初始化一个Partitioner,这个Partitioner计算的所有的区号都为0

排序概述

排序是MapReduce框架中最重要的操作之一,MapTask和ReduceTask均会对数据按照key进行排序,该操作属于Hadoop的默认行为,任何应用程序中的数据均会被排序,而不管逻辑上是否需要。默认排序是按照字典顺序排序,且实现该排序的方法是快速排序

排序分类

  • 部分排序

      MapReduce根据输入记录的键值对数据集排序,最终生成N个结果文件,每个文件内部整体有序
    
  • 辅助排序

     在进入reduce阶段时,通过比较key是否相同,将相同的key分为一组
    
  • 全排序

      对所有的数据进行排序,指生成一个结果文件,这个结果文件整体有序
    
  • 二次排序

      在对key进行比较时,比较的条件为多个
    
相关推荐
工业互联网专业7 分钟前
Python毕业设计选题:基于大数据的旅游景区推荐系统_django
大数据·vue.js·python·django·毕业设计·源码·课程设计
The Open Group16 分钟前
企业如何通过架构蓝图实现数字化转型
大数据·人工智能·分布式·微服务·云原生·架构·数字化转型
HZZD_HZZD33 分钟前
出租房管理系统有哪些?
大数据
全域观察1 小时前
两台手机如何提词呢,一台手机后置高清摄像一台手机前置提词+实时监测状态的解决方案来喽
大数据·人工智能·chatgpt·新媒体运营·程序员创富
笔墨登场说说2 小时前
git sonar maven 配置
大数据·elasticsearch·搜索引擎
VinciYan2 小时前
.NET使用TDengine时序数据库和SqlSugar操作TDengine
大数据·c#·.net·tdengine
来一杯龙舌兰2 小时前
【MongoDB】MongoDB的聚合(Aggregate、Map Reduce)与管道(Pipline) 及索引详解(附详细案例)
数据库·mongodb·mapreduce·索引·aggregate·pipline
guanpinkeji2 小时前
酒店民宿小程序,探索行业数字化管理发展
大数据·小程序·小程序开发·小程序制作·民宿小程序·酒店民宿小程序
Pioneer000013 小时前
Elasticsearch实战应用:构建高效的全文搜索引擎
大数据·elasticsearch
东皋长歌5 小时前
Flink安装和Flink CDC实现数据同步
大数据·flink