MapReduce系列之Mapper、Combiner和Reducer

  • Mapper类

MapReduce的Mapper类中共有四个父类的方法:setup()、map()、run()、cleanup()

setup()方法:在一个任务中,此方法只在开始执行一次,适用于对相关变量和资源的初始化操作。

map()方法:任务实现的主要过程在此方法中执行,只要FileInputFormat解析出KV对,则此方法便执行一次,重复执行直到Split文件处理完成。用户可以重写这个方法,但是默认的时候通常会调用setup而启动这个程序。这个函数默认并不做什么有用的 事情,但是可以被用户覆盖重写以便于设置任务(例如初始化类的变量),当设置完成之后,分片的每一个键值对会激发map()方法。因此map()接收到一个键,一个值,以及一个上下文context。使用这个上下文对象,一个map就会存储其输出到缓存中。

请注意,map分片是按块截取的(例如64kb),每一个块分割成为若干键值对的数据( SplitLineReader.class干的好事),这是在Mapper.Context.nextKeyValue内部完成的。当map分片被全部处理之后,run()会调用clean()方法。默认的,没有什么会被执行,除非用户重写覆盖他。

map会使用Mapper.Context.write()将map函数的输出溢写到内存中的环形缓冲区 (MapTask.MapOutputBuffer)。缓冲区的大小是固定的,通过mapreduce.task.io.sort.mb (default: 100MB)指定。
任何时候当这个缓冲区将要充满的时候(mapreduce.map. sort.spill.percent: 默认80% ),溢写将会被执行(这是一个并行过程,使用的是单独的线程,缓冲池还可以继续被写入)。如果溢写线程太慢,而缓冲区又忙了的话,map()就会暂停执行而等待。
溢写线程执行下面的动作:
1、创建一个溢写记录SpillRecord 和一个FSOutputStream 文件输出流(本地文件系统)
2、内存内排序缓冲中的块:输出的数据会使用快排算法按照partitionIdx, key排序
3、排序之后的输出会分割成为分区:每一个分区对应一个reduce
4、分区序列化写到本地文件

run()方法:提供了setup->map->cleanup执行的模版,一般此方法不重写,

cleanup()方法:此方法在一个任务中仅执行一次,实现变量和资源的释放工作。

   例子很多,用户必须要自己实现这个类。在驱动中指定定义的Mapper实现类:

job.setMapperClass(**Mapper.class);

 

  • Combiner类

       Mapper端的Reducer。但不能改变Mapper端的Key和Value的输出类型。

  • Reducer类

       和Mapper类似,但主要功能不同,主要是对Mapper的输出进行归约。

猜你喜欢

转载自blog.csdn.net/twj0823/article/details/84553303