大数据相关学习 2.MapReduce
·
大数据计算的核心思路是移动计算比移动数据更划算。既然计算方法跟传统计算方法不一样,那么用传统的编程模型进行大数据计算就会遇到很多困难,因此 Hadoop 大数据计算使用了一种叫作 MapReduce 的分布式计算框架。核心是将一个复杂的数据处理任务分解为两个主要阶段:Map(映射) 和 Reduce(归约)。
- Map 阶段(分):负责将输入数据分割成独立的片段,由多个 Map Task 并行处理。每个 Map 任务处理一条输入记录,输出一系列的中间键值对(key-value pairs)。这个过程类似于将一份长长的清单拆分成多个小项,分给不同的人同时清点。
- Reduce 阶段(合):负责对 Map 阶段输出的中间结果进行汇总。框架会将所有 Map 输出中具有相同 key 的值分组在一起,然后每个 Reduce Task 处理一组 key,最终生成汇总结果。这好比将不同人清点的同类物品数量相加,得到总数。
一个 MapReduce 作业的执行包含一系列精细的步骤,下图概括了其核心流程与关键组件交互:

输入与分片 (Input & Splitting)
InputFormat类负责验证输入数据的格式,并将输入数据(如 HDFS 上的大文件)逻辑切分成多个 分片 (Splits)。默认情况下,分片大小与 HDFS 的块大小一致。RecordReader则负责读取分片,并将其转化为一条条具体的键值对记录,作为 Map 函数的输入
Map 阶段
- 每个数据分片会由一个 Map Task 处理。Map 任务的数量通常由分片数决定。
- 开发者编写的
Mapper函数处理输入的键值对,并输出新的中间键值对。
Shuffle 与 Sort(洗牌与排序)
- Shuffle,将 Map 任务输出的中间结果按照 key 进行分区(
Partitioner),并通过网络传输到对应的 Reduce 任务节点。 - Sort,在数据送达 Reduce 任务之前,框架会对每个分区内的数据按照 key 进行排序。这确保了 Reduce 函数接收到的是已经分组和排序的数据。
Reduce 阶段
- 所有具有相同 key 的中间值会被分组,然后传递给同一个 Reduce 任务。
- 开发者编写的
Reducer函数接收一个 key 和对应的 value 迭代器,进行汇总计算(如求和、求平均等),并输出最终的键值对。
输出 (Output)
OutputFormat类负责将最终的键值对写入指定的存储系统,如 HDFS。
Combiner:是一个可在 Map 端执行的本地 Reduce 操作。它会对 Map 的本地输出进行初步合并,减少网络传输的数据量。例如,在词频统计中,可以先在 Map 端对同一个单词的出现次数进行局部求和。
Partitioner:决定了 Map 产生的中间键值对如何被分发给不同的 Reduce 任务。默认的分区策略是对 key 的哈希值取模,确保相同 key 去往同一个 Reduce 任务。
这是MP经典任务词频统计的执行过程

小文件问题
小文件问题是HDFS和MapReduce架构中的经典瓶颈,指的是大量远小于 HDFS 块大小的文件对系统造成的负面影响。它会导致NN和DN负担加重、任务执行低效、HDFS存储浪费等很多问题。
在MapReduce作业执行过程中,有些设置不合理会导致出现小文件问题。
Reduce任务数量过多
- MapReduce作业的输出文件数量通常由Reduce任务的数量决定。如果设置了过多的Reduce任务(例如,在Hive中通过
mapred.reduce.tasks参数设置得过高),每个Reduce任务都会生成一个独立的输出文件。当总数据量不大但Reduce任务很多时,每个任务处理的数据量就很少,从而产生大量小文件
数据严重倾斜
- 在存在数据倾斜的情况下,大部分数据可能被集中到一个或少数几个Reduce任务中处理,而其他大量的Reduce任务只分配到极少量的数据。这些处理数据量很少的Reduce任务输出的文件就是小文件。
源数据本身小文件
小文件的应对策略,核心思想是 “合并”:
- 输出时合并:对MapReduce作业而言,最有效的办法是在数据写入HDFS前就进行合并。在Hive中可以通过设置
hive.merge.mapfiles和hive.merge.mapredfiles等参数来自动合并Reduce阶段的输出文件。 - 使用特定文件格式:将小文件转换为SequenceFile或AVRO等容器型文件格式,可以将多个小文件打包成一个大的序列文件,减少文件数量,同时保持原始文件的边界信息。
- 使用归档工具:对于已经产生的、访问不频繁的历史小文件,可以使用Hadoop Archive (HAR) 工具将其打包存档,减轻NN的压力。
- 调整计算引擎:使用像CombineFileInputFormat这样的输入格式,它可以在Map任务启动前,将多个小文件逻辑上合并到一个InputSplit中,从而减少初始化的Map任务数量。
更多推荐
所有评论(0)