文章目录
- What is MapReduce?
- Map函数 & Reduce函数 - 计算逻辑
- Map函数:
- Reduce函数:
- 对分布式计算的支持
- 一次Map & Reduce中的一些实现细节
What is MapReduce?
👉🏿 MapReduce来自于人们对于数据处理方式的一种归纳实现(论文:MapReduce)
分为两类最小的粒度:一种是Map计算;一种是Reduce计算;
以这两种粒度的计算为基础,进行组合后,实现了一个复杂需求的计算框架-MapReduce
还有另一种计算框架 - 叫Spark
概念"Map(映射)“和"Reduce(归约)”
MapReduce是一种编程模型,用于大规模数据集(大于1TB)的并行运算。
Map函数 & Reduce函数 - 计算逻辑
输入数据集 → Map → 中间数据集 → Reduce → 最终数据集
Map函数:
接受一个键值对(key-value pair),产生一组中间键值对
MapReduce框架会将map函数产生的中间键值对里键相同的值传递给一个reduce函数
Map,是以一条记录为单位,进行数据映射处理(映射、变换、过滤,1进N出)!
Reduce函数:
接受一个键值对(key-value pair),产生一组中间键值对。MapReduce框架会将map函数产生的中间键值对里键相同的值传递给一个reduce函数
Reduce,是以一组数据(多条记录)为单位,做计算(分解、缩小、归纳),输出一个结果(一组进N出)!
👉🏿 Reduce需要前置的分组操作(用k做数据分组),以k-v形式组织数据,其实这个前置操作就是Map操作
对分布式计算的支持
👉🏿 分布式计算
强调并行度,以及节点间的协同
核心思想:分而治之、计算向数据移动
- reduce的计算,来自于map的输出!
- 联想到netty的并发和同步架构(map并发,同步聚合结果集,并发分组处理reduce)
- HDFS 的物理切块block & MapReduce 的 split分片
- block是物理的,split是逻辑的,目的是调用间的解藕!
- io密集型(适合split大一点)、cpu密集型(适合split小一点)
- 实际的业务场景是:一套业务数据,可能既要进行io密集型计算、也要进行cpu密集型计算
- 所以要进行 block 和 split 的解藕,控制map计算的数据粒度/并行度!
- 完成解藕之后,需要实现计算程序向存储节点的移动 - 计算向数据移动!
- 数据切割的时候怎么保证切割后的数据是完整的数据内容?
- 由框架实现保障 - 感觉有点像Netty的粘包和拆包
- reduce的并行度,由开发人员决定!
一次Map & Reduce中的一些实现细节
- split会经过format生成一个record,然后以record为单位调用map计算;
- map计算会输出一个res(k,v),然后这个res会经过一次分区计算,给这个res打上一个分区号p;
- map计算之后会将计算结果先写进Buffer[in memory],然后溢写disk;
- buffer在溢写时,会做一个2次排序[保证分区有序,且分区内key有序-归并排序算法]
- 未来相同的一组key便会排在一起,这会使得reduce在拉取分区数据之后按照key分组计算时的IO复杂度,指数级下降(O(n) → O(1))
- MapTask的输出是一个文件,存储在本机的文件系统中
- ReduceTask会先从不同的MapTask中获取自己分区的数据集,这个数据集可能是包含多个数据组,然后对数据按组进行归并,将归并后的数据进行reduce计算
- ReduceTask中的归并排序其实可以和reduce方法的计算同时发生,尽量减少IO,因为有迭代器模式的支持!