Hadoop系列九(MapReduce工作机制)

发布时间:2023年12月27日

MapReduce最核心的部分是它的MapTask阶段和ReduceTask阶段。可以简单的理解MapTask阶段用于将一行数据拆分成一个KV的数据,ReduceTask阶段是对Map阶段生成的KV数据做统计。

Hadoop的MapReduce的大致流程。

  1. 按照块对原始数据进行切片。比如一个文件200M,Hadoop会先将其在逻辑上分成128M+72M,这样就有两个块数据
  2. 每个块数据都会由一个MapTask来处理,MapTask最终生成分区数据。
  3. ReduceTask对所有MapTask的数据进行聚合

一、MapTask工作机制

MapTask主要分为6个阶段:Read阶段、Map阶段、Collect阶段、Spill阶段、Merge阶段

  1. Read阶段:MapTask通过InputFormat获取的RecordReader,从输入流中解析出K/V(Key/Value)数据,对于一个文件而言,K就是行号,V就是一行内容。
  2. Map阶段:该阶段属于用户自定义阶段(对应于Mapper类),接收Read阶段解析出的KV数据,解析并生成新的KV数据。
  3. Collect阶段:在Map阶段最后都需要将新生成的KV数据通过context.write()写出去,最终都会通过OutputCollector.collect()输出结果。在该函数内部还会调用Partitioner进行分区,最终会将数据写入到环形缓冲区。
  4. Spill阶段:也称“溢写”阶段,在Collect阶段会不断向环形缓冲区写入数据,环形缓冲的数据是存放在内存中的,当数据过多时(一般会将内存等分成2部分,写数据时先向一遍写入,当数据超过80%时,认为该部分数据已满,后续写入的数据会写道另一部分),需要将数据从内存写出到磁盘,在写磁盘之前,会对内存的中的数据做排序,并在必要时对数据进行合并(Combiner)、压缩。最终的数据会写到一个临时文件中。
  5. Merge阶段:对Spiil阶段产出的临时文件进行合并,最终生成一个数据文件。

对于Spill阶段做详细的说明,方便理解。

  1. ?利用快速排序对数据进行排序,排序的方式是,先按照分区进行排序,再按照Key进行排序,最后得到的数据以分区单位聚集在一起,且同一分区内数据按照Key有序。
  2. 按照分区编号将数据写入到临时文件output/spillN.out(N表示当前溢写次数中,如果设置了Combiner,则在写入之前会做以此数据聚集。
  3. 将分区数据的元信息写道内存索引数据结构(SpillRecord)中,其中每个分区的元信息包括:在临时文件中的偏移量、压缩前的数据大小、压缩后的数据大小。如果当前内存索引大小超过1MB,则将内存索引写到文件output/spillN.out(N表示当前溢写次数)中。

二、ReduceTask工作机制?

ReduceTask主要分为3个阶段:Copy阶段Sort阶段Reduce阶段

  1. Copy阶段:ReduceTask从MapTask上拷贝一片数据,并针对某一片数据,如果其大小超过一定阈值,则写到磁盘上,否则直接放到内存中。
  2. Sort阶段:在远程拷贝数据的同时,ReduceTask启动了两个后台线程对内存和磁盘上的文件进行合并,以防止内存使用过多或磁盘上文件过多。按照MapReduce语义,用户编写reduce()函数输入数据是按key进行聚集的一组数据。为了将key相同的数据聚在一起,Hadoop采用了基于排序的策略。由于各个MapTask已经实现对自己的处理结果进行了局部排序,因此,ReduceTask只需对所有数据进行一次归并排序即可。
  3. Reduce阶段:reduce()函数将计算结果写到HDFS上。

?三、ReduceTask并行决定机制

MapTask的数量可以根据切片的数量来决定。但是ReduceTask是可以手动设置的。

// 同时指定相应数量的ReduceTask
job.setNumReduceTasks(5);

关于Reduce数量的设置有一些注意事项:

  1. ReduceTask=0,说明没有Reduce阶段,输出文件的个数与Map个数相同。
  2. ReduceTask默认为1,所以输出一个文件。
  3. 如果数据分布不均匀,会在Reduce阶段产生数据倾斜。
  4. ReduceTask的数量不是随意设置的,需要根据业务来设置,如果需要全局的汇总统计,那么只能有一个ReduceTask。
  5. 具体有多少ReduceTask由集群性能决定。
  6. 如果分区数>1,但是ReduceTask=1,那么不会再进行分区,只有ReduceTask的数量>1时才会进行分区。
文章来源:https://blog.csdn.net/YinJuan791739156/article/details/135221441
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。