MapTask工作机制
(1)Read阶段:
job的提交流程:待读写的源数据由客户端进行切片划分,划分完成之后提交(切片信息、jar包、xml配置文件)给yarn,yarn开启MrAppMaster,MrAppMaster读取切片信息,根据切片个数决定开启MapTask的个数。
MrAppMaster启动后正式开启MapTask,由InputFormat读取数据(默认使用TextInputFormat)调用RecorderReader的reader()读取数据,数据格式:(k,v)=(偏移量,数据的一行内容)。
读取之后将数据返回给Mapper,进入Map阶段。
(2)Map阶段:
主要是将解析出的key/value交给用户编写map()函数处理,并产生一系列新的key/value。
(3)Collect收集阶段:
在用户编写map()函数中,当数据处理完成后,一般会调用OutputCollector.collect()输出结果(即环形缓冲区)。
在该函数内部,它会将生成的key/value分区(调用Partitioner),并写入一个环形内存缓冲区中。
缓冲区内部的数据全部都是按照分区的方式进行存储,当数据进入到环形缓冲区时就进行分区标记(会根据分区进入到不同的reduce),缓冲区一侧存数据,一侧存索引,当数据达到80%时进行反向溢写。溢写之前需要对分区中的数据进行排序(对索引使用快速排序)。
达到80%时进行反向溢写的原因:若数据达到100%时进行溢写,则需要等待数据溢写到磁盘才能继续写入环形缓冲区,导致效率低;当达到80%时进行反向溢写,此时开启一个线程进行溢写,保证正常运行。
(4)Spill溢写阶段:
当环形缓冲区满后,产生大量的溢写文件,MapReduce会将数据写到本地磁盘上,生成一个临时文件。
将数据写入本地磁盘之前,先要对数据进行一次本地排序,并在必要时对数据进行合并、压缩等操作。
(5)Merge阶段:
当所有数据处理完成后(即溢写完成后),MapTask对所有临时文件(溢写文件)进行一次归并排序,以确保最终只会生成一个数据文件,存储在磁盘上。
ReduceTask工作机制
前提:MapTask将数据处理完毕且持久化在磁盘上,等待ReduceTask端拉取数据。
当所以的MapTask完成之后启动相应数量的ReduceTask,并告知ReduceTask数据分区开hi工作。并不是等所有的MapTask完成之后才开启ReduceTask。
(1)Copy阶段:
ReduceTask从各个MapTask上远程拷贝一片数据(即拉取指定分区的数据),并针对某一片数据,如果其大小超过一定阈值,则写到磁盘上,否则直接放到内存中。
(2)Sort阶段:
对拉取的文件进行归并排序。相同的key的键值对进入到reduce()方法,排序有助于提高效率。
在远程拷贝数据的同时,ReduceTask启动了两个后台线程对内存和磁盘上的文件进行合并,以防止内存使用过多或磁盘上文件过多。按照MapReduce语义,用户编写reduce()函数输入数据是按key进行聚集的一组数据。为了将key相同的数据聚在一起,Hadoop采用了基于排序的策略。由于各个MapTask已经实现对自己的处理结果进行了局部排序,因此,ReduceTask只需对所有数据进行一次归并排序即可。
(3)Reduce阶段:
对于相同的key的数据进入到同一个reduce()处理函数,将计算结果**通过OutputFormat(输出)**的RecordWriter写到HDFS上。
MapReduce工作流程
1、输入数据接口:InputFormat
(1)默认使用的实现类是:TextInputFormat
(2)TextInputFormat的功能逻辑是:一次读一行文本,然后将该行的起始偏移量作为key,行内容作为value返回。
(3)CombineTextInputFormat可以把多个小文件合并成一个切片处理,提高处理效率。
2、逻辑处理接口:Mapper
用户根据业务需求实现其中三个方法:初始化setup()、用户的业务逻辑map()、关闭资源cleanup () 。
3、Partitioner分区
(1)有默认实现 HashPartitioner,逻辑是根据key的哈希值和numReduces来返回一个分区号;key.hashCode()&Integer.MAXVALUE % numReduces
(2)如果业务上有特别的需求,可以自定义分区。
4、Comparable排序
(1)当我们用自定义的对象作为key来输出时,就必须要实现WritableComparable接口,重写其中的compareTo()方法。
(2)部分排序:对最终输出的每一个文件进行内部排序。
(3)全排序:对所有数据进行排序,通常只有一个Reduce。
(4)二次排序:排序的条件有两个,自定义排序,实现writableCompare接口,重写compareTo方法。
5、Combiner合并
Combiner合并可以提高程序执行效率,减少IO传输。但是使用时必须不能影响原有的业务处理结果,进行提前聚合map,这是解决数据倾斜的一种方法。
6、逻辑处理接口:Reducer
用户根据业务需求实现其中三个方法:初始化setup()、用户的业务逻辑reduce()、关闭资源cleanup () 。
7、输出数据接口:OutputFormat
(1)默认实现类是TextOutputFormat,功能逻辑是:将每一个KV对,向目标文本文件输出一行。
(2)用户还可以自定义OutputFormat。