欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

MapTask运行机制详解以及Map任务的并行度

程序员文章站 2022-03-16 11:04:03
...

MapTask运行机制详解

MapTask运行机制详解以及Map任务的并行度
(图上左边蓝色应为MapperTask而不是MapperTack)

整个Map阶段流程大体如上图所示。

简单概述:

inputFile通过split被逻辑切分为多个split文件

通过RecordReader按行读取内容给map(用户自己实现的)进行处理

数据被map处理结束之后交给OutputCollector收集器,对其结果key进行分区(默认使用hash分区)

然后写入buffer

每个map task都有一个内存缓冲区,存储着map的输出结果,当缓冲区快满的时候,需要将缓冲区的数据以一个临时文件的方式存放到磁盘,当整个map task结束后再对磁盘中这个map task产生的所有临时文件做合并,生成最终的正式输出文件,然后等待reduce task来拉数据。

MapTask运行机制详解以及Map任务的并行度
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读取一行,用户重写的map就调用一次,并输出一个<key,value>。

4、Map输出的数据会写入内存,内存中这片区域叫做环形缓冲区,缓冲区的作用是批量收集map结果,减少磁盘IO的影响。

key/value对以及Partition的结果都会被写入缓冲区。

当然写入之前,key与value值都会被序列化成字节数组。

环形缓冲区其实是一个数组,数组中存放着key、value的序列化数据和key、value的元数据信息,包括partition、key的起始位置、value的起始位置以及value的长度。

环形结构是一个抽象概念。

缓冲区是有大小限制,默认是100MB。当map task的输出结果很多时,就可能会撑爆内存,所以需要在一定条件下将缓冲区中的数据临时写入磁盘,然后重新利用这块缓冲区。

这个从内存往磁盘写数据的过程被称为Spill,中文可译为溢写。

这个溢写是由单独线程来完成,不影响往缓冲区写map结果的线程。

溢写线程启动时不应该阻止map的结果输出,所以整个缓冲区有个溢写的比例spill.percent。

这个比例默认是0.8,也就是当缓冲区的数据已经达到阈值
(buffer size * spill percent = 100MB * 0.8 = 80MB),溢写线程启动,
锁定这80MB的内存,执行溢写过程。

Map task的输出结果还可以往剩下的20MB内存中写,互不影响。

5、合并溢写文件:每次溢写会在磁盘上生成一个临时文件(写之前判断是否有combiner)

如果map的输出结果真的很大,有多次这样的溢写发生,磁盘上相应的就会有多个临时文件存在。

当整个数据处理结束之后开始对磁盘中的临时文件进行merge合并,因为最终的文件只有一个,写入磁盘,并且为这个文件提供了一个索引文件,以记录每个reduce对应数据的偏移量。

至此map整个阶段结束。

mapTask的一些基础设置配置(mapred-site.xml当中设置):

设置一:设置环型缓冲区的内存值大小(默认设置如下)

mapreduce.task.io.sort.mb:100

设置二:设置溢写百分比(默认设置如下)

mapreduce.map.sort.spill.percent:0.80

设置三:设置溢写数据目录(默认设置)

mapreduce.cluster.local.dir:${hadoop.tmp.dir}/mapred/local

设置四:设置一次最多合并多少个溢写文件(默认设置如下)

mapreduce.task.io.sort.factor:10

MapTask运行机制详解以及Map任务的并行度

相关标签: MapReduce