MR中MapTask的工作机制
简单来说,inputFile通过split被切割成多个split文件通过Record按行读取内容给map,map中自己写处理的逻辑,map处理完之后交给OutputCollect收集器,对结果key进行分区(默认hashPartitioner),写入buffer,每个map task都有一个内存缓冲区(环形缓冲区),存放map的输出结果,当缓冲区快满的时候,将缓冲区的数据以临时文件的方式溢写到磁盘,整个map task结束后,对磁盘中这个maptask产生的所有临时文件进行合并,生成最终文件,等待reduce task拉取
- InputFormat(默认TextInputFormat)通过getSplits方法对输入目录文件进行切片得到block,有多少block就有多少MapTask
- 文件被切分成block之后,RecordReader(默认LineRecordReader)进行读取,以 \n 为分隔符,每次读取一行数据,返回键值对,key是首字符的偏移值,value表示一行文本的内容
- 读取的键值对进入用户继承的Mapper中,执行用户重写的map方法,RecordReader读取一行,调用一次map方法
- Mapper结束之后,将Mapper得到的结果通过Context.write进行collect收集。在collect中,先进行分区处理,默认使用hashPartitioner
- 将数据写入内存(环形缓冲区,默认100M) , 环形缓冲区的作用是:批量收集Mapper结果,减少磁盘IO的影响。 key,value,Partition的结果都会写入缓冲区,写入之前,需要序列化成字节数组
- 当环形缓冲区的内存达到百分之八十时,溢写线程启动,先将这百分之八十的key进行排序
- 合并溢写文件,每次溢写都会在磁盘上生成一个临时文件(判断是否有combiner),如果Mapper的输出结果很大,溢写线程多次启动,磁盘上就会产生多个临时文件。整个数据处理结束之后,对磁盘中的临时文件进行Merge合并。最终的文件只有一个写入磁盘,同时还会有一个索引文件,记录每个reduce对应的数据偏移量