Hadoop-MapReduce执行的全过程

    
在这里插入图片描述

  • Input Files:输入的数据存放在文件中,而这些文件通常存放在HDFS。这些文件的格式是任意的。例如,以行为单位的日志文件和二进制格式的文件。
  • InputFormat:InputFormat决定了输入数据如何切片(InputSplit)和读取(RecordReader)。常用的InputFormat类有FileInputFormat、TextInputFormat、KeyValueTextInputFormat、NLineInputFormat等。

Hadoop-MapReduce-CombineTextInputFormat,KeyValueTextInputFormat,NLineInputFormat,自定义InputFormat

  • InputSplit:逻辑切片,切片大小默认等于数据块大小。InputSplit由InputFormat生成。一个MapTask处理一个切片,MapTask数等于切片数。切片被分为多条记录,每条记录由Mapper处理。MapTask的位置由Hadoop决定,尽量靠近切片的位置(移动计算比移动数据更便宜)(局部性原理)。
        InputFormat的实现类调用 getSplit() 方法,计算每个文件的切片并获取切片,然后这些切片送到JobTracker。JobTracker利用切片信息规划MapTask,并将MapTask放到TaskTracker。MapTask将切片传进 createRecordReader(),获取RecordReader。
        注意,InputSplit不包含输入的数据,它只是封装了输入数据的元数据。

Hadoop-MapReduce-FileInputFormat切片getSplits()源码分析,MapReduce InputSplit(切片)与HDFS Block(块)对比

  • RecordReader:RecordReader由InputFormat定义。负责读取切片,将数据转换为Mapper能够读取(识别)的key-value键值对,然后将其送到Mapper,直到文件全部读取完。默认使用TextInputFormat转换数据为键值对,key为目标行的偏移量,value是目录行的内容。
  • Mapper:处理来自RecordReader的每条记录,然后产生新的键值对。Mapper的输出数据是中间数据,先写入到环形缓存区(一边写数据,一边写索引),当缓存容量占用到一定比例(默认80%),然后溢写到本地磁盘,而不是HDFS(将数据写入本地磁盘之前,先要对数据进行一次本地排序,并在必要时对数据进行合并、压缩等操作)。一个MapTask处理一个切片。每对KV对执行一次Map方法。当所有数据处理完后,MapTask会将所有临时文件合并成一个大文件(避免同时打开大量文件和同时读取大量小文件产生的随机读取带来的开销),并保存到文件file.out中,同时生成相应的索引文件file.out.index。
    溢写阶段详情
        步骤1:利用快速排序算法对缓存区内的数据进行排序,排序方式是,先按照分区编号Partition进行排序,然后按照key进行排序。
        步骤2:按照分区编号由小到大依次将每个分区中的数据写入任务工作目录下的临时文件spillN.out(N表示当前溢写次数)中。如果用户设置了Combiner,则写入文件之前,对每个分区中的数据进行一次聚集操作。
        步骤3:将分区数据的元信息写到内存索引数据结构SpillRecord中,其中每个分区的元信息包括在临时文件中的偏移量、压缩前数据大小和压缩后数据大小。如果当前内存索引大小超过1MB,则将内存索引写到文件spillN.out.index中。
  • Partitioner:Partitioner根据Mapper的输出数据的key进行分区。默认通过key的哈希值进行分区,拥有相同的key的数据会去到相同的分区,同时分区号从0开始。最终,每个分区将被送到每个Reducer(Reduce数等于分区数)。如果只有一个Reducer,那么不会产生分区。当有多个Reducer,才会产生分区。分区之后每个分区内会按照key进行快速排序,经过排序后,数据以分区为单位聚集在一起,且同一分区内所有数据按照key有序。
  • Combiner:该组件是可选的。用于汇总(聚合)Mapper的输出数据,相同key的数据汇总到一起,减少Mapper和Reducer之间的数据传输量,缩短传输时间,同时减轻Reduce端的负担。
  • Shuffle and Sort:上面产生的数据送到Reduce节点(运行着Reduce的DataNode)。Shuffle是洗牌的意思,通过网络传输数据到Reducer的过程(Mapper通知,Reducer主动拷贝)。当Mapper完成工作之前或之后,产生的中间数据将洗牌到Reducer。拷贝的过程中,如果数据大小超过一定阈值,则写到磁盘上,否则直接放到内存中。而在Reduce开始之前,因为数据来自不同的Mapper,这些数据需要归并,根据key 排序(Value没有被排序)(由于各个MapTask已经实现对自己的处理结果进行了局部排序,因此,ReduceTask只需对所有数据进行一次归并排序即可。),按照key分组,最终将其作为Reducer的输入。如果将ReduceTask的数量设置为0(job.setNumReduceTasks(0)),shuffle和sort将不会执行,任务将停止在Map阶段,Map阶段没有包含任何排序(除非自定义),输出文件个数等于Map个数。

Hadoop-MapReduce-Partitioner分区,WritableComparable全排序、区内排序、GroupingComparator分组排序,Combiner合并

  • Reducer:将Mapper的输出作为Reducer的输入,Reducer的输出为最终输出,存放到HDFS。Reduce更适合轻量级操作,可以对数据进行汇总、过滤、合并等操作。相同的key执行一次。

Hadoop-MapReduce-Reduce阶段调用reduce()方法过程源码分析

  • RecordWriter:将Reducer的输出的KV键值对写入到输出文件。
  • OutputFormat:将输出文件写入到HDFS或本地磁盘。OutputFormat决定了RecordWriter如何将输出数据写入文件。MapReduce默认的OutputFormat是TextOutputFormat,它的key和value可以是任意的,因为TextOutputFormat会调用 toString() 方法将它们转换为字符串。每对key和value用“ \t ”(tab)隔开(可以修改MapReduce.output.textoutputformat.separator)

Hadoop-MapReduce-自定义OutputFormat

猜你喜欢

转载自blog.csdn.net/H_X_P_/article/details/106128363