Hadoop三大组件之MapReduce(二)

1. MapReduce框架原理

1. InputFormat
  • 定义:InputFormat负责定义输入数据的格式和如何进行切分(splitting)。它将输入数据分为多个片段(splits),每个片段会被一个MapTask处理。
  • 作用 :例如,TextInputFormat会将文本文件按行读取,而SequenceFileInputFormat则用于处理二进制文件。
2. Input
  • 定义:Input是指要被处理的原始数据,这些数据可以存储在HDFS(Hadoop分布式文件系统)中,也可以是其他支持的存储系统。
  • 作用:输入数据是整个MapReduce作业的起点,所有后续处理都基于这个数据展开。
3. Mapper
  • 定义:Mapper是MapReduce的一个核心组件,它负责将输入数据的每个片段进行处理,生成中间键值对(key-value pairs)。
  • 工作流程
    • 接收分配给它的输入Split。
    • 处理每一条记录,产生一组中间的数据(KV对)。
    • 例如,在单词计数程序中,Mapper会将每个单词映射为键,并将其计数(通常为1)作为值。
4. Shuffle
  • 定义:Shuffle是MapReduce框架中的一个关键步骤,负责将Mapper输出的中间数据根据键进行排序和分组。
  • 作用
    • 首先,框架会将相同键的所有中间数据聚集到一起。
    • 然后会把这些数据按照Reducer的数量分区,以便后续的Reducer可以并行处理。
    • Shuffle阶段通常包括排序和分区的过程。
5. ReduceTask
  • 定义:ReduceTask是MapReduce的第二个核心组件,负责处理从Shuffle阶段传入的中间键值对。
  • 工作流程
    • 每个ReduceTask接收属于自己的中间数据。
    • 它将这些数据合并并聚合,通常是对相同键的值进行处理,例如求和或计数。
    • 最终,ReduceTask会生成最终的输出结果。
6. Reducer
  • 定义:Reducer是执行ReduceTask的具体实现,负责接收、处理和输出数据。
  • 工作流程
    • 接收来自Shuffle阶段的键值对。
    • 对相同键的值进行聚合。
    • 将结果输出到指定的存储位置。
7. OutputFormat
  • 定义:OutputFormat定义了输出数据的格式和如何存储输出结果。
  • 作用 :它可以指定输出结果是写入到文本文件、序列文件或其他格式中。例如,TextOutputFormat会将结果写入文本文件。
8. Output
  • 定义:Output是Reduce阶段最终生成的结果数据,这些数据通常会被存储在HDFS中。
  • 作用:输出数据是整个MapReduce作业的最终结果,供后续处理或分析使用。

2. 数据块与数据切片

1. 数据块(Block)

在HDFS(Hadoop Distributed File System)中,数据块是物理上将数据分成一块块的单位,是HDFS存储数据的基本单位。每个数据块通常默认大小为128MB(可以根据需要进行调整),并分布在集群的不同节点上。

2. 数据切片(Input Split)

数据切片是在逻辑上对输入数据进行分块,它并不代表在磁盘上的物理切分。数据切片是MapReduce程序计算输入数据的单位,每个切片会对应启动一个MapTask。切片的数量和大小直接影响MapTask的并行度。


3. FileInputFormat 切片机制

FileInputFormat 是MapReduce中默认的输入格式,负责将输入数据划分为切片。其切片机制如下:

  1. 按照文件内容长度进行切片:切片的大小根据文件的字节数来决定。
  2. 切片大小:默认情况下,切片大小等于HDFS的Block大小。
  3. 针对每个文件单独切片:切片机制不考虑整个数据集,而是对每一个文件单独进行处理。

示例

假设有两个文件 file1.txtfile2.txt,经过 FileInputFormat 切片机制后形成的切片信息如下:

  • file1.txt.split1:0-128
  • file1.txt.split2:128-256
  • file1.txt.split3:256-320
  • file2.txt.split1:0-10M

4. FileInputFormat 切片大小参数配置

切片大小的计算公式

切片大小的计算公式为:

java 复制代码
Math.max(minSize, Math.min(maxSize, blockSize));
  • mapreduce.input.fileinputformat.split.min.size:默认值为1。
  • mapreduce.input.fileinputformat.split.max.size:默认值为 Long.MAX_VALUE

默认情况下,切片大小等于Block大小。

切片大小设置

  • maxSize(切片最大值):如果该参数设定小于Block大小,切片将变小,等于配置的参数值。
  • minSize(切片最小值):如果该参数设定大于Block大小,切片将可能变得比Block大小更大。

5. Map和Reduce数量设置

1.Map任务数量

  • Map任务数量通常由输入数据的分片数量决定。可以通过以下方式来调整:
    • 调整块大小(Block Size):改变HDFS中数据块的大小。
    • 调整分片大小(Split Size):通过配置参数来改变分片的逻辑划分。

2.Reduce任务数量

  • Reducer的数量可以根据以下公式进行设置:
java 复制代码
Reduce数量=min(参数2,总数据量/参数1)
  • Reducer个数由Partition个数决定,Mapper生成的中间数据通过Shuffle过程进行分区,每个Partition的数据由对应的一个Reducer进行处理。因此,Reducer的数量始终大于或等于分区的数量。
  • Partition:每个Mapper在处理数据时,会根据预定义的分区函数(通常是哈希函数)来决定每个输出的键值对应该被发送到哪个Reducer。这意味着在Mapper输出时,已经在逻辑上将数据分配到了相应的分区。

6. 环形缓冲区的作用

环形缓冲区是为了解决数据传输和处理效率而设计的,它在Map和Reduce阶段之间扮演着至关重要的角色。其主要作用包括:

  1. 内存数据传输

    • 环形缓冲区允许在内存中进行数据传输,避免频繁的磁盘IO操作,从而提升处理速度。传统的Map和Reduce之间的数据传输依赖于磁盘,这会增加延迟和降低效率。
  2. 数据整理与排序

    • 在多个Map任务的输出数据被送入Reduce之前,环形缓冲区能够对这些数据进行整理和排序。这使得Reduce任务可以更高效地处理数据。
  3. 避免重复读取与写入

    • 环形缓冲区能够减少Map和Reduce之间数据的重复读取和写入,从而节省网络带宽。
  4. 内存重用

    • 环形缓冲区的设计允许重复利用内存,而无需频繁申请新的内存块。这有助于规避垃圾回收机制引发的性能问题。
  5. 结构组成

    • 环形缓冲区包含三个部分:空闲区、数据区和索引区。初始位置叫做equator,数据从equator的左侧写入,索引从右侧写入。当数据和索引的大小达到环形缓冲区的80%时,系统会进行以下操作:
      1. 在原地对已写入的数据进行快速排序,并将这些排好序的数据和索引spill到磁盘上。
      2. 更新equator的位置,并冲洗出旧的数据和索引。
      3. 如果在空闲的20%区域写入数据时,之前的80%数据尚未写入磁盘,程序将会进入待处理状态,直到有足够空间可供写入。

7. MapReduce的三次排序

在MapReduce的过程中,共进行了三次排序:

  1. Map输出排序

    • 当Map任务输出数据时,首先将数据写入环形缓冲区。达到阈值后,后台线程会将缓冲区的数据划分为相应的分区,并在每个分区内进行内排序。这一过程确保了Map阶段的输出是有序的。
  2. 溢写文件合并排序

    • 在Map任务完成之前,磁盘上会生成多个已分区且排好序的溢写文件。这些溢写文件的大小与缓冲区一致。合并这些文件时,仅需进行一次排序即可使最终输出文件整体有序。
  3. Reduce阶段的合并排序

    • 在Reduce阶段,将多个Map任务的输出文件复制到Reduce Task中进行合并。由于这些文件已经经过二次排序,因此在合并时再次排序可以确保输出文件的有序性。
相关推荐
Yaml41 小时前
Spring Boot 与 Vue 共筑二手书籍交易卓越平台
java·spring boot·后端·mysql·spring·vue·二手书籍
小小小妮子~1 小时前
Spring Boot详解:从入门到精通
java·spring boot·后端
hong1616881 小时前
Spring Boot中实现多数据源连接和切换的方案
java·spring boot·后端
aloha_7891 小时前
从零记录搭建一个干净的mybatis环境
java·笔记·spring·spring cloud·maven·mybatis·springboot
记录成长java2 小时前
ServletContext,Cookie,HttpSession的使用
java·开发语言·servlet
睡觉谁叫~~~2 小时前
一文解秘Rust如何与Java互操作
java·开发语言·后端·rust
程序媛小果2 小时前
基于java+SpringBoot+Vue的旅游管理系统设计与实现
java·vue.js·spring boot
小屁孩大帅-杨一凡3 小时前
java后端请求想接收多个对象入参的数据
java·开发语言
java1234_小锋3 小时前
使用 RabbitMQ 有什么好处?
java·开发语言
TangKenny3 小时前
计算网络信号
java·算法·华为