MapReduce原理解析

2020-07-09  本文已影响0人  一拳超疼

题记

本文资料来源于拉钩大数据开发高薪训练营。

MapTask运行机制详解

mapTask.png

步骤流程详解:

  1. ⾸先,读取数据组件InputFormat(默认TextInputFormat)会通过getSplits⽅法对输⼊⽬录中⽂
    件进⾏逻辑切⽚规划得到splits,有多少个split就对应启动多少个MapTask。split与block的对应关
    系默认是⼀对⼀。
  2. 将输⼊⽂件切分为splits之后,由RecordReader对象(默认LineRecordReader)进⾏读取,以\n
    作为分隔符,读取⼀⾏数据,返回<key,value>。Key表示每⾏⾸字符偏移值,value表示这⼀⾏
    ⽂本内容。
  3. 读取split返回<key,value>,进⼊⽤户⾃⼰继承的Mapper类中,执⾏⽤户重写的map函数。
    RecordReader读取⼀⾏这⾥调⽤⼀次。
  4. map逻辑完之后,将map的每条结果通过context.write进⾏collect数据收集。在collect中,会先
    对其进⾏分区处理,默认使⽤HashPartitioner。

MapReduce提供Partitioner接⼝,它的作⽤就是根据key或value及reduce的数量来决定当前的这对
输出数据最终应该交由哪个reduce task处理。默认对key hash后再以reduce task数量取模。默认的
取模⽅式只是为了平均reduce的处理能⼒,如果⽤户⾃⼰对Partitioner有需求,可以订制并设置到
job上。

  1. 接下来,会将数据写⼊内存,内存中这⽚区域叫做环形缓冲区,缓冲区的作⽤是批量收集map结
    果,减少磁盘IO的影响。我们的key/value对以及Partition的结果都会被写⼊缓冲区。当然写⼊之
    前,key与value值都会被序列化成字节数组。
  1. 当溢写线程启动后,需要对这80MB空间内的key做排序(Sort)。排序是MapReduce模型默认的⾏为!
  1. 合并溢写⽂件:每次溢写会在磁盘上⽣成⼀个临时⽂件(写之前判断是否有combiner),如果
    map的输出结果真的很⼤,有多次这样的溢写发⽣,磁盘上相应的就会有多个临时⽂件存在。当
    整个数据处理结束之后开始对磁盘中的临时⽂件进⾏merge合并,因为最终的⽂件只有⼀个,写⼊
    磁盘,并且为这个⽂件提供了⼀个索引⽂件,以记录每个reduce对应数据的偏移量。
    ⾄此map整个阶段结束!!

MapTask并行度

ReduceTask工作机制

ReduceTask

Reduce⼤致分为copy、sort、reduce三个阶段,重点在前两个阶段。copy阶段包含⼀个
eventFetcher来获取已完成的map列表,由Fetcher线程去copy数据,在此过程中会启动两个merge线
程,分别为inMemoryMerger和onDiskMerger,分别将内存中的数据merge到磁盘和将磁盘中的数据
进⾏merge。待数据copy完成之后,copy阶段就完成了,开始进⾏sort阶段,sort阶段主要是执⾏
finalMerge操作,纯粹的sort阶段,完成之后就是reduce阶段,调⽤⽤户定义的reduce函数进⾏处理。

详细步骤

ReduceTask并行度

ReduceTask的并⾏度同样影响整个Job的执⾏并发度和执⾏效率,但与MapTask的并发数由切⽚数决定
不同,ReduceTask数量的决定是可以直接⼿动设置:

// 默认值是1,⼿动设置为4
job.setNumReduceTasks(4);

注意事项

  1. ReduceTask=0,表示没有Reduce阶段,输出⽂件数和MapTask数量保持⼀致;
  2. ReduceTask数量不设置默认就是⼀个,输出⽂件数量为1个;
  3. 如果数据分布不均匀,可能在Reduce阶段产⽣倾斜;
上一篇 下一篇

猜你喜欢

热点阅读