目录
总结:
map函数--> partition分区函数(在内存中进行sort排序)-->combiner函数(如果存在,且会符合运行条件)-->map输出spill溢出临时文件(合并为一个已分区且排序的)-->copy(复制map的输出数据到reduce节点)-->合并map的输出文件(大于内存缓存区会溢出到磁盘,在合并阶段如果有combiner函数,也会运行,减少写入磁盘的数据量,压缩的map输出也会再内存中解压)-->合并map输出的数据文件为一个排序的文件输入reduce。
数据格式转换:
map: (K1, V1) → list(K2,V2)
combiner: (K2, list(V2)) → list(K2, V2) (如果存在,非必须,有些适合比如求最大值,词频统计,而有些不合适,如求均值)
reduce: (K2, list(V2)) → list(K3, V3)
map函数接收一个<key,value>形式的输入,然后同样产生一个<key,value>形式的中间输出,reduce函数接收一个如<key,(list of values)>形式的输入,然后对这个value集合进行处理,每个reduce产生0或1个输出,reduce的输出也是<key,value>形式的。
(1). map任务处理
1.1 读取输入文件内容,解析成key、value对。对输入文件的每一行,解析成key、value对。每一个键值对调用一次map函数。
1.2 写自己的逻辑,对输入的key、value处理,转换成新的key、value输出。
1.3 对输出的key、value进行分区。
1.4 对不同分区的数据,按照key进行排序、分组。相同key的value放到一个集合中。
1.5 (可选)分组后的数据进行归约。combiner处理
(2).reduce任务处理
2.1 对多个map任务的输出,按照不同的分区,通过网络copy到不同的reduce节点。
2.2 对多个map任务的输出进行合并、排序。写reduce函数自己的逻辑,对输入的key、value处理,转换成新的key、value输出。
2.3 把reduce的输出保存到文件中。
参数设置:
- MapReduce.task.timeout :map和reduce任务在指定的时间内没有向application master更新进度,就会被杀死,单位是毫秒,默认是10分钟,如果设置为0,将关闭超时判定,长时间运行的任务永远也不会被标记为失败,在这种情况下被挂起的任务永远不会被释放,随着时间的推移最终降低整个集群的效率,不建议;
- MapReduce.map.maxattempts、MapReduce.reduce.maxattempts 设置application master在任务失败后,重新调度该任务执行的次数,默认是4次;
- MapReduce.map.failures.maxpercent、MapReduce.reduce.failures.maxpercent 在一些作业中不希望一旦有少数几个任务失败就终止运行整个作业因为即使任务失败,作业的一些结果可能还是可用的,可以通过这两个参数来设置运行任务失败的最大百分比;
- MapReduce.am.max-attempts 设置application master任务失败后重试的次数,默认为2;
- yarn.app.mapreduce.am.job.recovery.enable 设置application master通过作业历史来恢复失败的应用程序所运行的状态,默认是true开启;
- yarn.resourcemanager.nm.liveness-monitor.expiry-interval-ms 单位毫秒,节点管理器向资源管理器发送心跳信息的最大时间间隔,超过了,资源管理器会通知停止发送心跳信息的节点管理器,并且将其从自己的节点池中移除以调度启动容器;
- mapreduce.task.io.sort.mb 默认100M,Map端数据排序可用内存缓冲区,如果内存充裕建议调大至256M或512M,可提升排序性能;
- mapreduce.map.sort.spill.percent 缓冲区的阈值,默认80%。达到阈值就会把缓冲区的内容写到磁盘上mapreduce.cluster.local.dir指定的目录下;
- mapreduce.task.io.sort.factor 把溢出文件合并成一个已分区且已排序的输出文件,这个参数控制着一次最多能够合并多少流,默认值是10;
- mapreduce.map.combine.minspills设置启用combiner的最少溢出文件的个数,默认为3,一旦少于,由于map输出规模的减少,不值得调用combiner;
- mapreduce.map.output.compress 是否把map的输出压缩输出到磁盘上,默认是不压缩false,开启是true;
- mapreduce.map.output.compress.codec 指定压缩格式;
- mapreduce.shuffle.max.threads reducer用于得到输出文件分区的工作线程数,默认值为0,将最多线程数设置为机器处理器数量的两倍;
- mapreduce.reduce.shuffle.parallelcopies 设置reduce从map输出数据copy数据到reduce任务节点的并发线程数;
1、 剖析MapReduce作业运行机制
![](https://i-blog.csdnimg.cn/blog_migrate/cdfde918fa131bb950adc73ddadf6479.png)
1.1、 作业的提交
![](https://i-blog.csdnimg.cn/blog_migrate/7536942f64ea363b85a06f43aad5bdf6.png)
1.2、 作业的初始化
![](https://i-blog.csdnimg.cn/blog_migrate/632aabd0f21d679b0fdbd211db91c460.png)
1.3、 任务的分配
![](https://i-blog.csdnimg.cn/blog_migrate/f39ba966fc02e8da056e1aa8ca28df6c.png)
1.4 、任务的执行
1.5、 进度和状态的更新
![](https://i-blog.csdnimg.cn/blog_migrate/591b8b1c587ce465b4737c143de89cab.png)
1.6、 作业的完成
![](https://i-blog.csdnimg.cn/blog_migrate/1c66a314f3fb3a402d5dfe1eac24f021.png)
2 、失败
2.1、 任务运行失败
![](https://i-blog.csdnimg.cn/blog_migrate/597b2213d8f5194d2cec1161b37732b2.png)
2.2、 application master运行失败
![](https://i-blog.csdnimg.cn/blog_migrate/21e9b9933ca2acf4d49f81fc4fb26748.png)
2.3 、节点管理器运行失败
![](https://i-blog.csdnimg.cn/blog_migrate/8d7905354cfe8234c655625e83a02849.png)
2.4 、资源管理器运行失败
![](https://i-blog.csdnimg.cn/blog_migrate/c7456207f7ad3aef2fe6ea2e9a26a2e2.png)
3、 shuffle和排序
![](https://i-blog.csdnimg.cn/blog_migrate/3b995f5e404b03f37ea94302dc4d5df0.png)
3.1 、map端
![](https://i-blog.csdnimg.cn/blog_migrate/907ff79db07b6017d55c0e2c63c6b9f0.png)
3.2、 reduce端
![](https://i-blog.csdnimg.cn/blog_migrate/7e4861f2eead62b80fe2e1cfdbb3be00.png)
3.3 、配置调优
![](https://i-blog.csdnimg.cn/blog_migrate/7af479a75954cba8d7173a829d3addcb.png)
4 、任务的执行
4.1 、任务执行环境
![](https://i-blog.csdnimg.cn/blog_migrate/46404dd17c9e2e0e183dd65ac91c6947.png)
4.2 、推测执行
![](https://i-blog.csdnimg.cn/blog_migrate/cdb865a7fc8bed49b8ee9f61b889c36d.png)
4.3 、关于OutputCommitters
5、Wordcount例子
最简单的MapReduce应用程序至少包含 3 个部分:一个 Map 函数、一个 Reduce 函数和一个 main 函数。在运行一个mapreduce计算任务时候,任务过程被分为两个阶段:map阶段和reduce阶段,每个阶段都是用键值对(key/value)作为输入(input)和输出(output)。main 函数将作业控制和文件输入/输出结合起来。
并行读取文本中的内容,然后进行MapReduce操作。
Map过程:并行读取文本,对读取的单词进行map操作,每个词都以<key,value>形式生成。
我的理解:
一个有三行文本的文件进行MapReduce操作。
读取第一行Hello World Bye World ,分割单词形成Map。
<Hello,1> <World,1> <Bye,1> <World,1>
读取第二行Hello Hadoop Bye Hadoop ,分割单词形成Map。
<Hello,1> <Hadoop,1> <Bye,1> <Hadoop,1>
读取第三行Bye Hadoop Hello Hadoop,分割单词形成Map。
<Bye,1> <Hadoop,1> <Hello,1> <Hadoop,1>
Reduce操作是对map的结果进行排序,合并,最后得出词频。
我的理解:
经过进一步处理(combiner可选),将形成的Map根据相同的key组合成value数组。
<Bye,1,1,1> <Hadoop,1,1,1,1> <Hello,1,1,1> <World,1,1>
循环执行Reduce(K,V[]),分别统计每个单词出现的次数。
<Bye,3> <Hadoop,4> <Hello,3> <World,2>
参考:
Hadoop权威指南.大数据的存储与分析.第4版--第7章 MapReduce的工作机制
https://www.cnblogs.com/hehaiyang/p/4484442.html
https://blog.csdn.net/wust__wangfan/article/details/48468125