hadoop ---mapreduce(映射化简)

版权声明: https://blog.csdn.net/u014384314/article/details/80481302


1.Map/Reduce是什么

大数据并行编程框架,由两个基本的步骤Map(映射)和Reduce(化简)组成,它隐藏了分布式计算中并行化、容错、数据分布、负载均衡等内部细节,实际的使用中普通编程人员/应用人员只需关系map/reduce两个过程的实现


2.Map/Reduce的框架原理


整个Map/Reduce框架包括3部分:JobClient、JobTracker、TaskTracker三部分组成,同时出入数据和输出数据是存储在HDFS中的。

JobClient:Map/Reduce客户端程序,负责向JobTracker发起分布式计算的请求,并上传分布式计算程序和配置文件。
JobTracker:可以说是Map/Reduce的中枢神经系统了,负责接收JobClient提交的分布式计算请求,并向TaskTracker分发计算任务,是整个Map/Reduce系统额资源管理者和协调者。

TaskTracker:负责具体的mapReduce任务的执行,并与JobTracker通信汇报自己的工作进展。

hadoop中Map/Reduce的任务的执行过程:

hdfs-->block--> map-->memory-->shuffle-->disk-->combine-->merge-->输出文件-->reduce-->hdfs

hadoop中一个Map/Reduce任务拆解为两个过程:Map过程和Reduce过程,两个过程可能在不同的计算节点上完成,以下是一个经典的Map/Reduce过程图:




3.1 map

我们从图的左边开始看,input split为从HDFS中读取过来的数据,由于HDFS中文件是按照block来组织的,在这里读取的时候,也是按照block读取进来开始计算的,一般来说,数据是边读取边计算的一个流式的过程。一个maptask会读取多个块的数据,数据读进来之后数据通过map映射,会转换会一些基本<key,value>的形式,这个时候并不是直接把map后的数据发送给reduce端,因为第一直接map后的数据是无序的、第二直送发送会占用大量的网络IO资源。因此在中间会经过一个shuffle的过程。

shuffle,其实就是将数据打乱再整理的一个过程,这样出来的数据就是干净有序的了。shuffle过程包括partition、sort、spill三个过程。

partition分区,分区数量就是 reduce 任务数量,即上图中 partitions ,默认情况下,只有一个分区,即只有一个 reduce 任务。线程根据处理数据需要的 reducetask总数量 把数据划分成相应的partition。具体划分:partition计算key的hash值,将hash对reducetask的数量求模 来确定要发送的reducetask的ID (实际上,由于key值得非均衡分布 这种算法可能会导致发送给某台reducetask的数据过多 而另外的reducetask收到的数据过程,hadoop允许我们自己实现partition接口来实现数据的均衡)。

sort: 每个 partition 中,后台进程按键进行内排序.

partition和sort都是在内存上操作

spill: 分区和排序后就生成溢出文件并保存到磁盘上,生成规则如下

每个 map 都有一个环形的内存缓冲区用于存储任务的输出,即上图中的 buffer in memory 。缓冲区默认大小为 100MB,可以通过改变 io.sort.mb 属性来调整。一旦缓冲内容达到阈值(io.sort.spill.percent,默认为 80%),一个后台线程就开始把内容溢出到(spill)磁盘。上图中,buffer in memory 后边的三个箭头分别对应三个溢出文件,每个文件上又有分区。在溢出写磁盘的过程中,map 输出继续写到缓冲区,但如果在此期间缓冲区被填满了,map 会被阻塞直到写磁盘过程完成。

溢出写磁盘时的位置:mapred.local.dir 属性指定的作业特定子目录中的目录中。

combine:在磁盘上分别对这三个溢出文件中具有相同key的key-value对,将其组合到一起并合并为1个key-value.(在单个溢出文件中和并),运行 combiner 使得每个 map 的输出结果更紧凑,可以减少写到磁盘的数据和传递给 reducer 的数据,因此减少的是在网络中传输的数据量。

注: combiner 这个过程不是都可以存在,在某些时候错误的使用 combiner 有可能会影响最后 reducer 的结果。

merge: 将这三个文件合并成一个已分区且已排序的输出文件(和并3个溢出文件并根据key-value对的key排序,不进行combine操作)。属性 io.sort.factor 控制一次最多能合并多少流,默认为10;

             map 的输出是可以进行压缩后再写磁盘的,可以节约磁盘空间以及加快磁盘写的速度。mapred.compress.map.output 设置为 true ,就可以开启压缩功能。使用的压缩库由 mapred.map.output.compression.codec 指定。

最后,要知道的是,map 的最后输出经常写到 map 任务的本地磁盘,但是,reduce 的输出并不是这样的。

每个maptask的工作量有大有小(从hdfs读取的块的个数不一样多),有的很早就完成了任务,有的还在辛勤工作,一部分完成了工作的maptask向JobTracker发送消息告知分配的任务已经完成。这个时候reducetask也没有闲着,reducetask向JobTracker发送消息,查询已经完成任务的maptask,并从该maptask的本地文件系统拉取数据,由于有很多的maptask,因此reducetask也会得到很多的小文件,reducetask拉取数据的同时会对这些文件做merge操作(对不同的maptask结果的数据进行merge),为即将开始的reduce任务做准备


3.2 reduce


1.根据reducetask1分析reduce :

从map输出的所有文件中分别同时拉取都在partition1中的数据--->sort and merge(两两maptask输出文件合并,并根据Key将key-value对排序)---->.......---->直到剩下一个集合且所有Key-value对都排好序时,进行reduce操作(combine操作)  --->将化简后的结果存入hdfs

猜你喜欢

转载自blog.csdn.net/u014384314/article/details/80481302