MapReduce是一个基于集群的计算平台,是一个简化分布式编程的计算框架,是一个将分布式计算抽象为Map和Reduce两个阶段的编程模型。(这句话记住了是可以用来装逼的)
1.MapReduce工作流程
0) 用户提交任务 (含数据)
1) 集群首先对输入数据源进行切片
2) master 调度 worker 执行 map 任务
3) worker 读取输入源片段
4) worker 执行 map 任务,将任务输出保存在本地
5) master 调度 worker 执行 reduce 任务,reduce worker 读取 map 任务的输出文件
6) 执行 reduce 任务,将任务输出保存到 HDFS
由上至下依次执行
过程 | 过程描述 |
---|---|
用户提交任务job 给集群 | |
切片 | 集群查找源数据 对源数据做基本处理 |
分词(每行执行一次map函数) | 集群(yarn的appliction)分配map任务节点worker |
映射 | 其中间数据(存在本地) |
分区(partition) | 中间数据 |
排序 (或二次排序) | 中间数据 |
聚合(combine有无key聚合后key无序) | 中间数据 分组(group) 发生在排序后混洗前(个人理解) |
混洗(shuffle后key有序) | 混洗横跨mapper和reducer,其发生在mapper的输出和reducer的输入阶段 |
规约(reduce) | 集群(yarn的appliction)分配reduce任务节点worker |
下面针对具体过程详细介绍:
2.切片split
HDFS 以固定大小的block 为基本单位存储数据,而对于MapReduce 而言,其处理单位是split。split 是一个逻辑概念,它只包含一些元数据信息,比如数据起始位置、数据长度、数据所在节点等。它的划分方法完全由用户自己决定。
Map任务的数量:Hadoop为每个split创建一个Map任务,split 的多少决定了Map任务的数目。大多数情况下,理想的分片大小是一个HDFS块
Reduce任务的数量: 最优的Reduce任务个数取决于集群中可用的reduce任务槽(slot)的数目 通常设置比reduce任务槽数目稍微小一些的Reduce任务个数(这样可以预留一些系统资源处理可能发生的错误)
3.Map()阶段
读取HDFS中的文件。每一行解析成一个<k,v>。每一个键值对调用一次map函数
重写map(),对第一步产生的<k,v>进行处理,转换为新的<k,v>输出
对输出的key、value进行分区
对不同分区的数据,按照key进行排序、分组。相同key的value放到一个集合中
4. Reduce阶段
多个map任务的输出,按照不同的分区,通过网络复制到不同的reduce节点上
对多个map的输出进行合并、排序。
重写reduce函数实现自己的逻辑,对输入的key、value处理,转换成新的key、value输出
把reduce的输出保存到文件中
特别说明:
切片 不属于map阶段,但却是map阶段的输入,是集群对输入数据的解析处理
分词,映射,分区,排序,聚合 都属map阶段
混洗 横跨map阶段和reduce阶段,其发生在map阶段的输出和reduce的输入阶段
规约 属reduce阶段 规约结果是reduce阶段的输出,输出格式由集群默认或用户自定义
分词即map()函数的输入与map阶段的输入略有差别,他的输入是切片结果的kv形式,行号(偏移量)与行内容
5.总结
执行步骤:
1)map任务处理——>切片
- 读取输入文件内容,解析成key、value对,输入文件的每一行,就是一个key、value对,对应调用一次map函数。
- 写自己的逻辑,对输入的key、value(k1,v1)处理,转换成新的key、value(k2,v2)输出。
2)reduce任务处理——>计算
- 在reduce之前,有一个shuffle的过程对多个map任务的输出进行合并、排序、分组等操作。
- 写reduce函数自己的逻辑,对输入的key、value(k2,{v2,…})处理,转换成新的key、value(k3,v3)输出。
- 把reduce的输出保存到文件中。