一、大致流程
- 这幅图简单的描述了整个MapReduce的流程,忽略很多细节,只保留核心思想。
- 1、首先InputData要先上传到HDFS上面,因为整个MapReduce依赖于HDFS。
- 2、InputFormat需要从HDFS上面读取数据,进行数据处理,得到一系列data split。关于InputFormat,可以看第二幅图:
- InputFormat:MapReduce框架基础类之一。主要包含两个操作:数据分隔:Data Splits,记录读取器:Record Reader。
- Data Splits:如何将数据分片,例如可以规定多少行为一片。
- Record Reader:如何读取分片中的数据,比如按行读取。每读取一条记录,调用一次map函数。
- 3、InputFormat最终会得到一系列data split,当然data solit会有很多,而map节点则要少的多,如何均匀的分配这么多data split,当然还是Hash算法.
- 4、当data split到达相应的map,map通常是进行数据加工的地方,因此我们会自己定义数据加工逻辑,然后以key value的形式进行输出,框架以制表符\t来区分key和value,因此我们经常和\t面基╰(°▽°)╯。
- 5、当数据以(key,value) 的形式从map出来后,由图一可知,这些键值对会经过一个称为shuffle(洗牌)&sort的过程,而在图二详细的描述了这个过程,图二的左边是Mapper阶段,右边是Reducer阶段,Mapper阶段完成后,会告诉Reducer来取:
- shuffle:神奇发生的地方,性能优化大有可为。由图三可知Shuffle包含多个过程,其中第一个是Partitioner(分隔):
- Partitioner:决定数据由哪个Reducer处理,从而分区。因为我们可能有多个Reducer这是非常有必要的,例如采用hash,可以对key取模,决定哪一个key由哪一个Reducer来处理。
- MemoryBuffer:内存缓冲区,每个map的结果和partition处理的 key value结果都保存在缓存中 。
- Spill:内存缓冲区达到阈值时,溢写spill线程锁住这80M 的缓冲区,开始将数据写出到本地磁盘中,然后释放内存。每次溢写都生成一个数据文件。溢出的数据到磁盘前会对数据进行key排序sort,以及合并combiner。
注意,溢出的数据到磁盘前会对数据进行key排序sort,这是框架会自动做的
发现相同Reduce的key数量,会拼接到一起,减少 partition的索引数量。
- shuffle:神奇发生的地方,性能优化大有可为。由图三可知Shuffle包含多个过程,其中第一个是Partitioner(分隔):
- 6、经过Spill的过程,这无疑会生成许多小文件,因此后面还会有一个merge on disk,会将一个mapper上面生成的小文件根据partitions合并成一个大文件。这在图二由详细的描述。
- 7、然后继续看图二,还会有一个fetch(取来)的过程,这时Copy phase阶段典型操作,它会根据partition,将各个Mapper上面对应的Reduce应该处理的数据(key,value)copy到对应的Reduce,上图只给出了一个Mapper和Reducer。
- 8、然后还会有一系列merge和sort,通过对key排序,将数据整合给Reduce处理,Reduce处理的过程和Mapper阶段类似,面对大量数据当然也会有:MemoryBuffer,Spill & Sort过程。
- 9、Reduce: 多个reduce任务输出的数据都属于不同的 partition,因此结果数据的key不会重复。合并reduce的输出文件即可得到最终的结果。
注意:
- 在顾及每个Mapper和Reducer处理的过程的细节的时候,还要跳出来,以全局的视角(即系统中会有多个Mapper和Reducer)观察思考,为什么设计的这么复杂。
网友评论