Hadoop —— MapReduce完整工作流程

前置总述

MapReduce是Hadoop生态里的分布式计算框架 。简单一句话:把一个超大文件,拆成很多小块,多台机器并行做Map处理;处理完的数据按类别分组,汇总交给Reduce做合并统计,最后输出结果存入HDFS 。示例场景:一个400M的cart.txt购物日志文件,统计各个城市的订单数量。

核心名词

先一次性讲清楚(后面流程会用到):

  1. 分片(Split) :输入文件的逻辑划分。默认一个HDFS的block对应一个分片 ;一个分片启动1个MapTask。分片不是物理切割文件,只是记录:这个任务要读文件哪一段。
  2. MapTask(Map任务) :Map阶段的最小执行单元,并行运行。负责读取分片数据,执行我们写的map函数,提取需要的字段,输出<key,value>键值对。
  3. 环形缓冲区(环形缓存) :Map节点内存里一块固定大小的内存区域(图例子100M),用来临时存放Map输出的<key,value>。
  4. 溢写(Spill) :环形缓冲区快要写满(默认达到80%),就把内存里的数据分区、排序,写入本地磁盘,生成临时小文件。
  5. 分区(Partition) :给键值对分类。默认用hash算法,同一个key会分到同一个分区;一个分区最终交给一个ReduceTask。比如城市名称做key,武汉全部分到分区0、深圳分到分区1。
  6. 归并排序:把多个无序文件,合并成有序文件。分为两次:①溢写时每个分区内部排序;②磁盘多个小文件合并(合并归并)。
  7. ReduceTask(Reduce任务):Reduce阶段最小执行单元。拉取所有MapTask输出的、属于自己分区的数据,分组,执行reduce聚合逻辑。
  8. Shuffle(洗牌阶段) :Map输出之后,Reduce接收之前的整套流程(分区、排序、溢写、文件合并、数据网络传输)。Shuffle是MapReduce最核心、最耗时的阶段,作用就是把相同key的数据汇集到一起,交给同一个Reduce。

完整分步流程

阶段一:Map阶段(并行读取、处理原始数据)

步骤1:文件分片

原始文件cart.txt400M,HDFS默认block块128M,会切分成多个block。MapReduce读取文件时,默认1个block生成1个分片split,1个分片启动1个MapTask。

本例4个block → 4个分片 → 启动MapTask1、MapTask2、MapTask3、MapTask4,4个Map任务并行跑在不同节点。

步骤2:执行Map逻辑(map函数)

每个MapTask读取自己对应的分片里的一行行文本数据,运行map函数。以城市订单统计举例:读取一行日志武汉,订单11,map函数提取出key=武汉,value=1,输出键值对 (武汉,1)。所有输出的<key,value>不会直接发给Reduce,先写入环形缓冲区。

步骤3:环形缓冲区 + 溢写(Spill)

环形缓冲区是内存空间(示例100M),不断接收Map输出的<key,value>。当缓冲区数据占用达到阈值(默认80%),触发溢写:

  1. 先对缓冲区里的数据分区:根据key计算hash,分配到对应分区;
  2. 分区内部做快速排序(按key排序);
  3. 将排好序的数据写入当前机器本地磁盘,生成一个临时小文件。

剩下20%缓冲区空间,继续接收Map新输出的数据,不中断Map计算。如果Map持续输出大量数据,会多次溢写,在磁盘产生很多个有序小文件。

步骤4:磁盘小文件合并(归并)

当这个MapTask全部数据处理完毕,磁盘上已经有很多次溢写产生的小文件。Map任务会读取这些本地小文件,执行合并归并:同一个分区内的多个有序文件,合并成一个更大的有序文件。

每个MapTask最终在本地磁盘,生成按分区划分、分区内部有序的文件。文件中,相同key的数据是挨在一起的。

阶段二:Shuffle阶段(跨节点数据拉取,Map到Reduce的数据传输)

步骤5:Reduce拉取属于自己分区的数据

ReduceTask启动后,会去所有已经完成的MapTask节点,拉取属于自己分区的数据。举例子:Reduce0负责"武汉"分区 → 去4个Map节点,拉取每个Map输出文件里属于武汉分区的数据。Reduce1负责深圳分区,同理拉取所有Map里深圳的键值对。

这个网络拉取的过程,就是Shuffle的一部分。Reduce拿到从不同Map节点传过来的多段有序数据,在Reduce本地再次归并排序,把相同key全部聚合在一起。

阶段三:Reduce阶段(聚合汇总)

步骤6:执行Reduce逻辑

Reduce把同一个key的所有value放到一组。比如key=武汉,拿到一组数据:(武汉,1)、(武汉,1)、(武汉,1)...运行reduce函数,对这一组value做聚合求和,得到结果 (武汉,1006)。同理,深圳、天津、重庆各自聚合统计。

步骤7:输出结果写入HDFS

每个ReduceTask执行完成,生成一个结果文件。

规则:一个ReduceTask输出一个结果文件,写入分布式文件系统HDFS。文件内容就是聚合完成的最终键值对,本例:武汉:1006、深圳:988、天津:987、重庆:956。

整体逻辑一句话总结

大文件分片,多Map并行读取原始数据,输出键值对;Map端通过环形缓冲区溢写、分区排序,落地本地磁盘;Shuffle阶段,Reduce从所有Map节点拉取属于自己分区的数据、再次归并;Reduce把相同key的数据分组聚合,计算最终结果,输出文件保存到HDFS。

容易踩坑的知识点

  1. ❌ 误区:Map的结果直接通过网络发给Reduce
    ✅ 正确:Map先写到本机磁盘临时文件,Reduce主动上门拉取,不是Map推送。
  2. ❌ 误区:分片=block,二者完全一样
    ✅ 正确:block是HDFS物理存储块;分片split是MapReduce逻辑读取划分,默认一一对应,但可以手动修改分片大小。
  3. ❌ 误区:Shuffle只是网络传输
    ✅ 正确:Shuffle包含分区、排序、溢写、本地文件合并、网络拉取、Reduce端归并整套流程,是MapReduce性能瓶颈点。
  4. ❌ 误区:一个key可以分给多个Reduce任务
    ✅ 正确:分区规则决定,同一个key一定会分到同一个分区,交给同一个ReduceTask,保证相同key全部在一处聚合。
相关推荐
小田学Python2 小时前
工具调用:让 Agent 从“说”到“做”
大数据·大模型·agent·ai工具·deepseek
GrowingIO技术社区6 小时前
用户行为分析怎么做?从业务目标到改进验证的完整流程
大数据·数据挖掘·数据分析
瑞克-桑切斯9 小时前
docker Harbor 单机部署手册
大数据·运维·elasticsearch·docker·容器
演艺大赏11 小时前
NiFi 起不来、登不上、节点被挤掉:一份按日志定位的排错清单
大数据
freejackman11 小时前
【实战三】撕开脱敏盲区:深度解析 CASE WHEN 与窗口函数血缘
大数据·数据库·sql
wafrdggh1 天前
2026电商快递批量查询怎么用?固乔助手模板设置评测
大数据·数据库·小程序
大大大大晴天1 天前
OLTP、OLAP、数据湖、数据集市、湖仓一体到底是什么关系?
大数据
正在走向自律1 天前
AI Agent 落地这一年:从“能跑起来”到“敢放出去”
大数据·人工智能·ai agent·智能体·mcp·a2a
freejackman1 天前
【实战二】字段级血缘追踪:拆解 AST 迷局,精准穿透函数链与子查询
大数据·数据库·sql
goujunwe1 天前
GEO 内容的“可摘录性”打磨技巧:段落、表格、小标题怎么写,方便大模型提取独立答案块
大数据·人工智能