MapReduce 分布式计算框架
指用户提交的 MapReduce 应用程序,是计算请求的载体。核心功能:提交作业、跟踪进度、访问任务报告、获取集群状态。提交流程:检查输入输出格式→计算 InputSplit→复制 jar 包和配置→提交到 ResourceManager。提交方法:Job.submit ()(立即返回)、Job.waitForCompletion (boolean)(等待完成)。大量数据集中分配到单个分区,导致部
·
一、认识 MapReduce
1. 核心思想
- 分而治之:将大数据拆分为独立数据块,分布式处理后汇总结果。
- 抽象为 Map 和 Reduce 操作:Map 处理数据生成中间结果,Reduce 聚合中间结果输出最终值。
- 隐藏系统细节:自动实现并行化、任务调度、容错等底层操作。
2. 编程模型
- 定义:分布式离线并行计算框架,适用于 PB 级以上海量数据处理。
- 特点:易于编程、扩展性好、高容错、支持离线处理。
- 核心阶段:
-
- Map 阶段:读取数据并解析为键值对(K-V 对)。
- Reduce 阶段:对 K-V 对归并排序,计算最终结果。
- 执行流程:数据分块→Map 任务读取处理→生成 K-V 对→Reduce 任务聚合→输出结果。
3. 经典案例 ——WordCount
- 问题:统计 PB 级英文文件中单词出现次数。
- 解决思路:
-
- Map 阶段:拆分文件,统计单个文件中单词出现次数,输出(单词,1)。
- Reduce 阶段:累加同一单词在不同文件中的次数,输出(单词,总次数)。
- 编程步骤:实现 Mapper→实现 Reducer→创建 MapReduce 作业→打包运行。
二、MapReduce 作业解析
1. 作业(Job)定义
- 指用户提交的 MapReduce 应用程序,是计算请求的载体。
- 核心功能:提交作业、跟踪进度、访问任务报告、获取集群状态。
- 提交流程:检查输入输出格式→计算 InputSplit→复制 jar 包和配置→提交到 ResourceManager。
- 提交方法:Job.submit ()(立即返回)、Job.waitForCompletion (boolean)(等待完成)。
2. 资源调度
- 核心模块:客户端(提交作业)、ResourceManager(资源调度)、NodeManager(启动任务)、ApplicationMaster(管理作业)、分布式文件系统(存储文件)。
- 调度流程:客户端提交作业→ResourceManager 分配资源→NodeManager 启动 Container→ApplicationMaster 运行任务。
3. 运行流程
- Map 阶段:FileInputFormat→InputSplit→RecordReader→Mapper→Partition→Sort→Combiner。
- Reduce 阶段:Reducer→FileOutputFormat→RecordWriter。
三、MapReduce 工作原理
1. Map Task 工作原理
- 输入数据:InputFormat 分割文件为 InputSplit,每个 split 对应一个 Map Task。
- 中间结果处理:数据写入内存缓冲区(默认 100MB),达到 80% 阈值时溢写到磁盘。
- 排序与合并:溢写前对 Key 排序,多个溢写文件最终合并为一个文件。
2. Reduce Task 工作原理
- 数据拉取:Map Task 完成后,Reduce Task 拉取对应分区的中间结果。
- 数据合并:合并拉取的数据,为 Reduce 计算做准备。
- 结果输出:执行 Reduce 算法,将结果写入 HDFS。
四、Shuffle 阶段
1. 概念
- 指 Mapper 之后到 Reducer 之前的过程,将无规则中间数据转换为有序数据。
- 分为 Map 端 Shuffle 和 Reduce 端 Shuffle。
2. Map 端 Shuffle
- Partition 分区:根据 Key 和 Reduce 数量分配数据所属的 Reduce Task。
- 环形缓冲区:缓存中间结果,满 80% 溢写磁盘。
- Spill 溢写排序:溢写前按分区和 Key 排序,可执行 Combiner 优化。
- Merg 文件合并:多个溢写文件合并为一个最终文件。
3. Reduce 端 Shuffle
- Copy 复制:通过 Http 方式拉取 Map 端对应分区数据。
- Merge 合并:数据存入缓冲区,满阈值溢写磁盘,最终合并为 Reduce 输入数据。
- Reduce 执行:处理合并后的数据,输出结果到 HDFS。
五、MapReduce 编程组件
1. InputFormat 组件
- 功能:定义作业输入规范,拆分文件为 InputSplit,创建 RecordReader。
- 常用子类:FileInputFormat(设置输入路径)、TextInputFormat(默认,按行读取)等。
2. OutputFormat 组件
- 功能:定义作业输出规范,转换输出格式以支持跨系统互操作。
- 输出规则:输出文件数与 Reduce 任务数一致,默认文件名为 part-r-00000。
- 常用子类:TextOutputFormat(默认,文本格式)、SequenceFileOutputFormat(序列文件格式)等。
3. RecordReader 和 RecordWriter
- RecordReader:从 InputSplit 读取 K-V 对,默认 LineRecordReader(偏移量为 Key,行数据为 Value)。
- RecordWriter:将 Reduce 输出的 K-V 对写入文件系统,核心方法为 write ()(写入数据)和 close ()(关闭输出)。
4. Partitioner 组件
- 功能:决定 Map 输出的 Key 分配给哪个 Reduce Task,数量与 Reduce 任务数一致。
- 默认实现:HashPartitioner(按 Key 的 Hash 值取模分配)。
- 自定义分区:可解决数据倾斜问题,按业务规则分配数据。
5. Combiner 组件
- 功能:Map 阶段的 Mini Reduce,合并相同 Key 的中间结果,减少网络传输量。
- 适用场景:累加求和、取最大值等(不影响最终结果的操作),不适用于求平均值。
六、优化 —— 数据倾斜
1. 问题定义
- 大量数据集中分配到单个分区,导致部分节点忙碌、其他节点空闲,降低处理效率。
2. 解决方法
- 自定义分区:按业务规则均匀分配数据。
- 重新设计 Key:给 Key 添加随机数,避免集中分配。
- 使用 Combiner:提前合并相同 Key 数据,减少传输量。
- 增加 Reduce 任务数:分散数据处理压力。
- 增加 Jvm 内存:提升单个节点数据处理能力。
七、经典案例
1. 排序
- 部分排序:默认排序方式,每个 Reduce 输出按 Key 排序,全局无序。
- 全排序:所有 Reduce 输出全局有序,实现方式包括单 Reduce 任务、自定义分区、Key 采样。
2. 倒序索引
- 功能:统计单词在各文件中的出现次数,支持按单词查询文件位置。
- 实现步骤:准备多文件数据→编写 Mapper(输出(单词 - 文件名,1))→Reducer(聚合次数)→运行作业。
3. Join
- 功能:关联多个数据源的数据(如姓名与城市编号关联)。
- 实现步骤:准备关联数据→编写 Mapper(输出(关联键,数据类型 - 数据))→Reducer(按关联键合并数据)→输出结果。
4. 平均分以及百分比
- 功能:计算学生平均分,统计各分数段人数占比。
- 实现思路:Map 阶段计算平均分并标记分数段→Reduce 阶段统计各分数段人数→计算百分比。
5. 过滤敏感词汇
- 功能:从文档中过滤指定敏感词。
- 实现步骤:准备文档和敏感词库→编写 Mapper(匹配敏感词并过滤)→Reducer(输出过滤后内容)→运行作业。
更多推荐


所有评论(0)