MapReduce初探

  1、概述。

  “MapReduce作业(job)是客户端需要执行的一个工作单元。Hadoop将作业分成若干个小任务(task)来执行,其中包括两类任务:map任务和reduce任务。

  有两类节点控制着作业执行过程:一个jobtracker及一系列tasktracker。jobtracker通过调度tasktracker上运行的任务,来协调所有运行在系统上的作业。tasktracker在运行任务的同时将运行进度报告发送给jobtracker,jobtracker由此记录每项作业任务的整体进度情况。如果其中一个任务失败,jobtracker可以在另外一个tasktracker节点上重新调度该任务。”“目前,Hadoop没有处理jobtracker失败的机制——它是一个单点故障。”

  “Hadoop将MapReduce的输入数据划分成等长的小数据块,称为输入分片。Hadoop为每个分片构建一个map任务。

  对于大多数作业来说,一个合理的分片大小趋向于HDFS的一个块的大小,默认是64MB,不过可以针对集群调整这个默认值。

  Hadoop在存储有输入数据(HDFS中的数据)的节点上运行map任务,可以获得最佳性能。这就是所谓的数据本地化优化。现在我们应该清楚为什么最佳分片的大小应该与块大小相同:因为它是确保可以存储在单个节点上的最大输入块的大小。如果分片跨越两个数据块,那么对于任何一个HDFS节点,基本上都不可能同时存储这两个数据块,因此分片中的部分数据需要通过网络传输到map任务节点。与使用本地数据运行整个map任务相比,这种方法显然效率更低。

  map任务将其输出写入本地硬盘,而非HDFS。因为map的输出是中间结果:该中间结果由reduce任务处理后才产生最终输出结果。如果该节点上运行的map任务在将map中间结果传送给reduce任务之前失败,Hadoop将在另一个节点上重新运行这个map任务以再次构建map中间结果。

  排过序的map输出需通过网络传输发送到运行reduce任务的节点。数据在reduce端合并,然后由用户定义的reduce函数处理。reduce的输出通常存储在HDFS中以实现可靠存储。对于每个reduce输出的HDFS块,第一个复本存储在本地节点上,其他复本存储在其他机架节点中。”

  Map(映射,会过滤坏数据)和Reduce(归约,化简)阶段都以可选择类型的键值对作为输入和输出。

  网上关于MapReduce的一个简短的解释:假设我们要数图书馆中所有的书。你数1号书架,我数2号书架,这是"Map"。我们人越多,数得就越快。最后我们聚到一起,把所有人的统计结果相加,这是"Reduce"。

 

  2、map。以下引号中的文字摘选自《hadoop权威指南》第6章:

  “每个map任务都有一个环形内存缓冲区(默认io.sort.mb=100MB),用于存储任务的输出。一旦缓冲内容达到阈值(默认io.sort.spill.percent=80%),一个后台线程便开始把内容写到(spill)磁盘中。在写磁盘过程中,map输出继续被写到缓冲区,但如果在此期间缓冲区被填满,map会阻塞直到写磁盘过程完成。”

  “在写磁盘之前,线程首先根据数据最终要传送到的reducer把数据划分成相应的分区(partition)。在每个分区中,后台线程按键进行内排序,如果有一个combiner,它会在排序后的输出上运行。”

  partitioner默认根据key的hash值,决定怎样将map输出分配到reducers上。如果分配不均匀则会产生数据倾斜。

  “一旦内存缓冲区达到溢出写的阈值,就会新建一个溢出写文件,因此在map任务写完其最后一个输出记录之后,会有几个溢出写文件。在任务完成之前,溢出写文件被合并(merge)成一个已分区且已排序的输出文件。io.sort.factor控制着一次最多能合并多少流,默认值是10。”

  

 

  3、reduce。以下引号中的文字摘选自《hadoop权威指南》第6章:

  “reducer通过HTTP方式得到(map)输出文件的分区。

  reduce的运行分为三个阶段:copy -> sort -> reduce。

  “reduce任务需要集群上若干个map任务的map输出作为其特殊的分区文件。每个map任务的完成时间可能不同,因此只要有一个任务完成,reduce任务就开始复制其输出。这就是reduce任务的复制阶段(一般也称为shuffle过程)。reduce任务有少量(默认mapred.reduce.parallel.copies=5个)复制线程,因此能够并行取得map输出。”

  “如果map输出相当小,则会被复制到reduce tasktracker的内存(大小由mapred.job.shuffle.input.buffer.percent控制,指定用于此用途的堆空间的百分比),否则map输出被复制到磁盘。一旦内存缓冲区达到阈值大小(mapred.job.shuffle.merge.percent)或达到map输出阈值(mapred.inmem.merge.threshold),则合并后溢出写到磁盘中。”

 

 

  4、shuffle和排序。以下引号中的文字摘选自《hadoop权威指南》第6章:

  “MapReduce确保每个reducer的输入都按键排序。系统执行排序的过程——将map输出作为输入传给reducer——称为shuffle。shuffle属于不断被优化和改进的代码库的一部分。从许多方面来看,shuffle是MapReduce的‘心脏’。”

 

 

  参考资料:

  1、以上引号中的文字摘选自《hadoop权威指南》

  2、参考链接:

  http://www.alidata.org/archives/1470

  http://blog.csdn.net/athenaer/article/details/8203990

 

 

不断学习中。。。

posted on 2014-11-25 20:54  han'er  阅读(797)  评论(0编辑  收藏  举报

导航