MapTask运行机制详解

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

简单概述

inputFile通过split被逻辑切分为多个split文件,
通过Record按行读取内容给map(用户自己实现的)进行处理,
数据被map处理结束之后交给OutputCollector收集器,对其结果key进行分区(默认使用hash分区),
然后写入buffer,每个map task都有一个内存缓冲区,
存储着map的输出结果,
当缓冲区快满的时候需要将缓冲区的数据以一个临时文件的方式存放到磁盘,
当整个map task结束后再对磁盘中这个map task产生的所有临时文件做合并,
生成最终的正式输出文件,然后等待reduce task来拉数据。

Map阶段详解

详细步骤:

1.首先,读取数据组件InputFormat(默认TextInputFormat)会通过getSplits方法对输入目录中文件进行逻辑切片规划得到splits,有多少个split就对应启动多少个MapTask。默认情况下split与block的对应关系默认是一对一。Block块默认大小是128M 那么split分割时也是按照128分割

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

个人理解—Map 输出数据到内存

map输出的数据写入环形缓冲区(内存),缓冲区的默认大小是100M(可修改)。
当数据达到阈值(默认0.8-可修改)时,环形缓冲区进行flash,
环形缓冲区:数据在输出的同时,数据也可以写入空余的空间内。
当flash的数据个数达到一定的数量时(默认4个)。对数据进行合并(merge)。

ReduceTask 工作机制

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

Reduce阶段详解

详细步骤

1、Copy阶段,简单地拉取数据。Reduce进程启动一些数据copy线程(Fetcher),通过HTTP方式请求maptask获取属于自己的文件。

2、Merge阶段。这里的merge如map端的merge动作,只是数组中存放的是不同map端copy来的数值。Copy过来的数据会先放入内存缓冲区中,这里的缓冲区大小要比map端的更为灵活。merge有三种形式:内存到内存;内存到磁盘;磁盘到磁盘。默认情况下第一种形式不启用。当内存中的数据量到达一定阈值,就启动内存到磁盘的merge。与map 端类似,这也是溢写的过程,这个过程中如果你设置有Combiner,也是会启用的,然后在磁盘中生成了众多的溢写文件。第二种merge方式一直在运行,直到没有map端的数据时才结束,然后启动第三种磁盘到磁盘的merge方式生成最终的文件。

3、合并排序。把分散的数据合并成一个大的数据后,还会再对合并后的数据排序。

4、对排序后的键值对调用reduce方法,键相等的键值对调用一次reduce方法,每次调用会产生零个或者多个键值对,最后把这些输出的键值对写入到HDFS文件中。

个人理解----Reduce在Map拷贝数据

Map 输出的结果写入本地,reduce主动发出拷贝进程到Map端拷贝数据。
reduce获取大数据后,将数据写入内存,当数据达到阈值时进行flash.
当flash的个数达到一定的量时,进行合并,最终发送给reduce

MapReduce总体工作机制


map逻辑完之后,将map的每条结果通过context.write进行collect数据收集。在collect中,会先对其进行分区处理,默认使用HashPartitioner。
MapReduce提供Partitioner接口,它的作用就是根据key或value及reduce的数量来决定当前的这对输出数据最终应该交由哪个reduce task处理。默认对key hash后再以reduce task数量取模。默认的取模方式只是为了平均reduce的处理能力,如果用户自己对Partitioner有需求,可以订制并设置到job上。

当溢写线程启动后,需要对这80MB空间内的key做排序(Sort)。排序是MapReduce模型默认的行为,这里的排序也是对序列化的字节做的排序。

如果job设置过Combiner,那么现在就是使用Combiner的时候了。将有相同key的key/value对的value加起来,减少溢写到磁盘的数据量。Combiner会优化MapReduce的中间结果,所以它在整个模型中会多次使用。

哪些场景才能使用Combiner呢?从这里分析,Combiner的输出是Reducer的输入,Combiner绝不能改变最终的计算结果。Combiner只应该用于那种Reduce的输入key/value与输出key/value类型完全一致,且不影响最终结果的场景。比如累加,最大值等(求平均值绝不能用Combiner)。Combiner的使用一定得慎重,如果用好,它对job执行效率有帮助,反之会影响reduce的最终结果。

Split对数据进行逻辑切分

hdfs数据块大小是128 ,split 逻辑切分数据块大小是128M
HDFS 128 是存储层面的概念,是切分数据的分界点。
split 128 是一个逻辑切分。
这两个128没有关系。

Shuffle阶段是在Map的输出到Reduce的输入

流程角度

内存角度

MapTask运行机制详解以及Map任务的并行度,ReduceTask 工作机制以及reduceTask的并行度,MapReduce总体工作机制相关推荐

  1. 【大数据day14】——MapReduce的运行机制详解(案列:Reduce 端实现 JOIN, Map端实现 JOIN,求共同好友)

    文章目录 1 .MapReduce的运行机制详解 1.1:MapTask 工作机制 详细步骤 配置 1.2 :ReduceTask 工作机制 详细步骤 1.3:Shuffle 过程 2. 案例: Re ...

  2. android系统(63)---Jobscheduler运行机制详解

    android之Jobscheduler运行机制详解 如果想在将来达到一定条件下执行某项任务时,可以在一个实现了JobService的子类的onStartJob方法中执行这项任务,使用JobInfo的 ...

  3. SSL / TLS 协议运行机制详解

    转载自  SSL / TLS 协议运行机制详解 互联网的通信安全,建立在SSL/TLS协议之上. 本文简要介绍SSL/TLS协议的运行机制.文章的重点是设计思想和运行过程,不涉及具体的实现细节.如果想 ...

  4. JavaScript 运行机制详解(理解同步、异步和事件循环)

    1.为什么JavaScript是单线程? JavaScript语言的一大特点就是单线程,也就是说,同一个时间只能做一件事.那么,为什么JavaScript不能有多个线程呢?这样能提高效率啊. Java ...

  5. 我看朴灵评注阮一峰的《JavaScript 运行机制详解:再谈Event Loop》

    阮一峰和朴灵对我来说都是大牛,他们俩的书我都买过,阮老师的译作<软件随想录>和朴灵的<深入浅出node.js>.这个事情已经过了4个月了,所以我拿来讲应该也没啥问题. 这件事情 ...

  6. python语言程序的特点_Python语言概述及其运行机制详解

    即日起,我们将打开一个新的编程世界的大门--Python语言.Python是一种跨平台的计算机程序设计语言.是一种面向对象的动态类型语言,最初被设计用于编写自动化脚本(shell),随着版本的不断更新 ...

  7. Python语言概述及其运行机制详解

    即日起,我们将打开一个新的编程世界的大门--Python语言.Python是一种跨平台的计算机程序设计语言.是一种面向对象的动态类型语言,最初被设计用于编写自动化脚本(shell),随着版本的不断更新 ...

  8. Hadoop之Shuffle机制详解

    Hadoop之Shuffle机制详解 目录 Shuffle机制 Partition分区 WritableComparable排序 Combiner合并 GroupingComparator分组(辅助排 ...

  9. Hadoop之Yarn工作机制详解

    Hadoop之Yarn工作机制详解 目录 Yarn概述 Yarn基本架构 Yarn工作机制 作业提交全过程详解 1. Yarn概述 Yarn是一个资源调度平台,负责为运算程序提供服务器运算资源,相当于 ...

最新文章

  1. 在docker的Linux容器搭建前端开发环境
  2. vue在开发环境怎么兼容ie_Vue兼容ie9的问题全面解决方案
  3. python提取个十百千位数字_实现人脸识别、人脸68个特征点提取,或许这个 Python 库能帮到你!...
  4. JavaScript实现integerPartition整数划分算法(附完整源码)
  5. 在.Net项目中使用Redis作为缓存服务
  6. java双缓存机制_详解JVM类加载机制及类缓存问题的处理方法
  7. 小米3c虚拟服务器,小米路由器3C固件逆向与测评-新手向
  8. python编程软件哪个好-推荐10 款最好的 Python IDE
  9. 头条小程序登录40014 bad params
  10. 【Socket】苍老师有了丈夫,我也有了SAEA
  11. 啃完这本阿里手册,应届七面进阿里
  12. 【vue】vue安装卡住/报错
  13. 华为稳定服务器在哪里找,哪个平台的服务器稳定
  14. 使用FFmpeg库实现视频编码
  15. Mysql+Canal1.1.5+Es实现数据同步
  16. 看不懂NFT,了解这几幅画就好了
  17. 编程语言排行榜:你选对了吗?
  18. 办公网络设置代理服务器
  19. xp系统安装教程图解
  20. FM收音机模块单片机实现

热门文章

  1. 单例模式的使用和应用场景
  2. 【计算机视觉】数字图像处理(四)—— 图像增强
  3. Redis启动与设置密码
  4. Python操作AutoCAD开发环境概述(Windows)
  5. python——每日一题
  6. 支付宝支付功能(一)
  7. 【老生谈算法】MATLAB生成雪花图片源码——生成雪花图片
  8. drawrect导致内存暴涨分析
  9. 七月三日服务器维护,7月3日服务器例行维护公告
  10. CAD参数绘制多行文字(com接口)