MapReduce之Mapper中的方法分析

来源:互联网 发布:数据库和表的关系 编辑:程序博客网 时间:2024/05/12 22:30

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()方法:此方法在一个任务中仅执行一次,实现变量和资源的释放工作。


0 0