一、左边客户端提交任务、生成 MapTask1-4 步骤HDFS 存放 200m 待处理文本 ss.txt客户端提交 Job 前按默认 128MB 切片200m 文件拆分为两个分片0-128、128-200打包程序 jar、任务配置文件提交 YARNYARN 的 AM 根据分片数量创建 MapTask分片数量 MapTask 数量本例 2 个分片对应 2 个 MapTask。二、中间MapTask 内部执行 Map 端 Shuffle5-11图核心环形缓冲区5~7 读取数据、执行 map 逻辑写入环形缓冲区TextInputFormatRecordReader 读取分片每行数据封装成k,v执行自定义 map () 业务逻辑context.write 输出键值对所有数据先写入100M 环形缓冲区缓冲区分为两块一块存原始 kv 数据一块存索引元数据。8 分区标记每条数据写入缓冲区时通过分区器计算分区编号标记这条数据最终交给哪个 ReduceTask。9 溢写 Spill缓冲区占用 80% 触发缓冲区内存达到 80% 阈值后台线程把缓冲区数据溢写到本地磁盘生成 spill 临时文件 每个溢写文件内部先按分区划分每个分区内的 key 有序。10 Combiner 局部合并可选性能优化每次生成 spill 溢写文件时执行 Combiner相当于本地小型 Reducer在 Map 端提前聚合相同 key减少磁盘 IO 和网络传输量注意不能修改 kv 类型。11 全部溢写文件归并 Merge当前 Map 所有 spill 文件生成完毕后多路归并全部临时文件最终每个 Map 只输出 1 个磁盘文件 文件内按分区存放同一个分区内 key 全局有序不同分区之间互不干扰。三、Reduce 端 Shuffle 流程图前置两个 MapTask 输出的文件已按分区划分partition0 数据全部交给 ReduceTask1partition1 交给 ReduceTask2。12 AM 等待所有 Map 完成启动 ReduceTask必须等全部 MapTask 执行结束AM 才会创建对应数量的 ReduceTask并告知每个 Reduce 只拉取指定分区的数据。13 Copy 远程拉取数据Shuffle 核心网络阶段Reduce 开启多线程远程连接所有 Map 所在节点拉取属于自己分区的数据 少量数据存入内存缓冲区内存占满后写入本地磁盘最终得到多份有序小文件。 例Reduce1 拉取 Map1、Map2 的 partition0 全部数据Reduce2 拉取两个 Map 的 partition1 数据。14 多路归并排序将拉取到的多份有序文件合并生成一份全局按 key 升序排列的完整数据。15 Grouping 分组通过分组比较器把 key 相同的所有 value 归为一组一组数据一次性传入 reduce 方法。16 执行 Reduce 逻辑输出结果到 HDFS执行自定义 reduce (key, 一组 value) 聚合逻辑context.write 输出最终 kv通过 TextOutputFormat、RecordWriter 写入 HDFS一个 ReduceTask 生成一个结果文件命名规则 part-r-00000、part-r-00001。完整流程总结读取 HDFS 文件切片→MapTask 执行 map 逻辑→数据写入环形缓冲区分区标记→缓冲区满溢写磁盘 Combiner 预聚合→所有溢写文件归并生成分区有序中间文件 全部 Map 执行完成后AM 启动 ReduceReduce 远程拉取对应分区数据本地多路归并排序按 key 分组执行 reduce 聚合最终输出文件到 HDFS。