`

Hadoop MapTask / ReducerTask

 
阅读更多

学习MapTask的内部实现。 
         
         整体执行流程 
 
         如上图示,MapTask的整个处理流程分五个阶段: 
         ●read阶段:通过RecordReader从InputSplit分片中将数据解析成一个个key/value。 
         ●map阶段:将由RecordReader解析出的key/value交给map()方法处理,并生成一个个新的key/value。 
         ●collect阶段:将map()中新生成key/value由OutpCollector.collect()写入内存中的环形数据缓冲区。 
         ●spill阶段:当环形缓冲区达到一定阀值后,会将数据写到本地磁盘上,生成一个spill文件。在写文件之前,会先将数据进行一次本地排序,必要的时候(按配置要求)还会对数据进行压缩。 
         ●combine阶段:当所有数据处理完后,将所有的临时的spill文件进行一次合并,最终之生成一个数据文件。 
     
         接下来我们会对该流程中最重要的collect、spill和combine三个阶段进行更深入的学习。 
         Collect过程 
         前阶段的map中新生成key/value对后,会调用OutpCollector.collect(key,value),在该方法内部,先调用Partitioner.getPartition()获取该记录的分区号,然后将<key,value,partition>传给MapOutputBuffer.collect()作进一步的处理。 
         MapOutputBuffer内部使用了一个内部的环形的缓冲区来暂时保存用户的输出数据,当缓冲区使用率达到一定阀值后,由SpillThread线程将缓冲区中的数据spill到本地磁盘上,当所有的数据处理完毕后,对所有的文件进行合并,最终只生成一个文件。该数据缓冲区直接用想到MapTask的写效率。 
         环形缓冲区使得collect阶段和spill阶段可以并行处理。 
         MapOutputBuffer内部采用了两级索引结构,涉及三个环形的内存缓冲区,分别是kvoffsets、kvindices和kvbuffer,这个环形缓冲区的大小可以通过io.sot.mb来设置,默认大小是100MB,图示如下: 

         kvoffsets即偏移量索引数组,用于保存key/value在kvindices中的偏移量。一个key/value对在kvoffsets数组中占一个int的大小,而在kvindices数组中站3个int的大小(如上图示,包括分区号partition,key的起始位置和value的起始位置)。 
         当kvoffsets的使用率超过io.sort.spill.percent(默认为80%)后,便会触发SpillTread线程将数据spill到磁盘上。 
         kvindices即文职索引数组,用于保存实际的key/value在数据缓冲区kvbuffer中的起始位置。 
         kvbuffer即数据局缓冲区,用于实际保存key/value,默认情况下可使用io.sort.mb的95%,当该缓冲区使用率使用率超过io.sort.spill.percent后,便会触发SpillTread线程将数据spill到磁盘上。 

         Spill过程 
         在collect阶段的执行过程中,当内存中的环形数据缓冲区中的数据达到一定发之后,便会触发一次Spill操作,将部分数据spill到本地磁盘上。SpillThread线程实际上是kvbuffer缓冲区的消费者,主要代码如下:

Java代码  收藏代码
  1. spillLock.lock();  
  2. while(true){  
  3.    spillDone.sinnal();  
  4.    while(kvstart == kvend){  
  5.       spillReady.await();  
  6.    }  
  7.    spillDone.unlock();  
  8.    //排序并将缓冲区kvbuffer中的数据spill到本地磁盘上  
  9.    sortAndSpill();  
  10.    spillLock.lock;  
  11.    //重置各个指针,为下一下spill做准备  
  12.    if(bufend < bufindex && bufindex < bufstart){  
  13.       bufvoid = kvbuffer.length;  
  14.    }  
  15.    vstart = vend;  
  16.    bufstart = bufend;  
  17. }  
  18. spillLock.unlock();  
  19.            


         sortAndSpill()方法中的内部流程是这样的: 
         第一步,使用用快速排序算法对kvbuffer[bufstart,bufend)中的数据排序,先对partition分区号排序,然后再按照key排序,经过这两轮排序后,数据就会以分区为单位聚集在一起,且同一分区内的数据按key有序; 
         第二步,按分区大小由小到大依次将每个分区中的数据写入任务的工作目录下的临时文件中,如果用户设置了Combiner,则写入文件之前,会对每个分区中的数据做一次聚集操作,比如<key1,val1>和<key1,val2>合并成<key1,<val1,val2>>; 
         第三步,将分区数据的元信息写到内存索引数据结构SpillRecord中。分区的元数据信息包括临时文件中的偏移量、压缩前数据的大小和压缩后数据的大小。 

         Combine过程 
         当任务的所有数据都处理完后,MapTask会将该任务所有的临时文件年合并成一个大文件,同时生成相应的索引文件。在合并过程中,是以分区文单位进行合并的。 
         让每个Task最终生成一个文件,可以避免同时打开大量文件和对小文件产生随机读带来的开销。

 

我们先看一下ReduceTask操作流程: 

        从流程图中我们可以看出,ReduceTask分5个阶段: 
        Copy阶段 
        Merge阶段 
        Sort阶段 
        Reduce阶段 
        Write阶段 
        其中的Copy阶段和Merge阶段是并行进行的。默认情况下ReduceTask同时启动5个MapOutputCopier线程从各个Mapper端的中间数据结果copy数据,放大小超过一定阀值后,则存放到磁盘上,否则直接放到内存中。 
        为了防止内存或磁盘上的文件数据太多,ReduceTask会启动后台线程分别对内存和磁盘上的数据文件进行合并操作。 
        当数据copy完后,还要经过Sort排序阶段对所有数据按key进行排序操作,将相同的key对应的value汇聚到一起,然后交给reduce()方法处理。 
        经过reduce()方法对数据进行处理后,然后将数据写到HDFS上。

分享到:
评论

相关推荐

    Windows平台下Hadoop的Map/Reduce开发

    讲述了Windows平台的Hadoop安装... 最后,以最简单的求和为例,剖析Hadoop的Map/Reduce工作机制,对于初学Hadoop及Map/Reduce的读者有很大的帮助。相信通过最简单的求和为例,读者可步入Hadoop的Map/Reduce开发者行列。

    hadoop中map/reduce

    hadoop中map/reduce自学资料合集

    hadoop/etc/hadoop/6个文件

    hadoop/etc/hadoop/6个文件 core-site.xml hadoop-env.sh hdfs-site.xml mapred-site.xml yarn-env.sh yarn-site.xml

    hadoop之map/reduce

    hadoop开发文档

    hadoop安装过程中的问题

    Hadoop/etc/hadoop/slaves 的IP地址要变。 5个重要的配置文件逐个检查,IP地址需要变 2.配置文件确认无错误,看日志: 从logs日志中寻找slave的namenode为什么没有起来。 3.最后发现是hdfs中存在上次的数据,删掉...

    hadoop/bin/hadoop.dll

    在windows环境下安装hadoop环境的时候,会缺少该文件。

    elephantdb, 在从Hadoop导出键/值数据时,分布式数据库专用.zip

    elephantdb, 在从Hadoop导出键/值数据时,分布式数据库专用 ElephantDB 0.5.1 ( cascalog-2.x ) ElephantDB 0.4.5 ( cascalog-1.x )ElephantDB是一个专门用于从Hadoop导出键/值数据的数据库。 Elephant

    Hadoop源代码分析(MapTask)

    Hadoop的MapTask类源代码分析

    Hadoop/HDFS/MapReduce/HBase

    对Hadoop中的HDFS、MapReduce、Hbase系列知识的介绍。如果想初略了解Hadoop 可下载观看

    hadoop-lzo-master

    1.安装 Hadoop-gpl-compression ...1.2 mv hadoop-gpl-...bin/hadoop jar /usr/local/hadoop-1.0.2/lib/hadoop-lzo-0.4.15.jar com.hadoop.compression.lzo.LzoIndexer /home/hadoop/project_hadoop/aa.html.lzo

    hadoop-lzo-0.4.20.jar

    cp /opt/hadoopgpl/lib/hadoop-lzo-0.4.20-SNAPSHOT.jar $HADOOP_HOME/share/hadoop/common/ cp /opt/hadoopgpl/lib/hadoop-lzo-0.4.20-SNAPSHOT.jar $HBASE_HOME/lib/ 2.2.6. 拷贝本地库so文件到hadoop tar -cBf - ...

    Hadoop学习笔记

    bin/hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-2.7.2.jar *** 输入文件目录 输出文件目录 *** 本地运行案例 bin/hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-2.7.2.jar ...

    hadoop2.2.0/2.6.0/2.7.0/2.7.1 64位安装包

    hadoop2.2.0/2.6.0/2.7.0/2.7.1 64位安装包。

    mac hadoop2.6.0 lib/native

    mac下Hadoop native library,用于解决报错:WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform… using builtin-java classes where applicable。再次说明,本版本只适用于mac ...

    hadoop.contrib/lucene源码

    hadoop框架,mapreduce利用Lucene构建倒排索引的源码!

    hadoop-native-lib-x64-2.7.3.tar.gz

    hadoop: true /taidl/hadoop/lib/native/libhadoop.so zlib: true /lib64/libz.so.1 snappy: true /taidl/hadoop/lib/native/libsnappy.so.1 lz4: true revision:99 bzip2: false openssl: true /lib64/libcrypto....

    eclipse连接hadoop插件2.6.0/5 2.7.3

    用于eclipse连接hadoop使用到的插件包,这里有几个版本的,不同的eclipse版本可以使用的插件包不一样,需要注意。

    hadoop/bin/winutils.exe

    windows环境下安装hadoop环境,在bin文件夹内会缺少此文件

    远程调用执行Hadoop Map/Reduce

    NULL 博文链接:https://sgq0085.iteye.com/blog/1879442

    重新编译好的contain-executor文件,指向/etc/hadoop/container-executor.cfg

    所以需要重新编译Container-executor,这边提供重新编译好的,默认加载配置文件路径/etc/hadoop/container-executor.cfg 使用方法: 1 替换/$HADOOP_HOME/bin/下的container-executor 2 创建/etc/hadoop目录,并将...

Global site tag (gtag.js) - Google Analytics