zoukankan      html  css  js  c++  java
  • Hadoop 学习之MapReduce

    MapReduce充分利用了分而治之,主要就是将一个数据量比较大的作业拆分为多个小作业的框架,而用户需要做的就是决定拆成多少份,以及定义作业本身,用户所要做的操作少了又少,真是Very Good!

    一.MapReduce执行流程

    下面的是MapReduce的执行过程:

       最上方的用户程序链接了底层的MapReduce库,并实现了最基本的Map函数和Reduce函数。

       由用户来决定将任务划分为K块(这里设为5),假设为64MB,如图左方所示分成了split0~4(文件块);然后使用fork将用户程序拷贝到集群内其它机器上。

       用户程序的副本中有个称为Master,其余称为worker,Master是负责任务调度的,为空闲worker分配作业(Map作业或Reduce作业),worker数量可由用户指定的。

       被分配了Map作业的worker,开始读取对应文件块的输入数据(包含多个map函数),从输入数据中抽取出键值对,每一个键值对都作为参数传递给map函数,map函数产生的中间键值对被缓存在内存中。

       缓存的中间键值对会被定期写入本地磁盘。主控进程知道Reduce的个数,比如R个(通常用户指定)。然后主控进程通常选择一个哈希函数(一致性哈希)作用于键并产生0~R-1个桶编号。Map任务输出的每个键都被哈希起作用,根据哈希结果将Map的结果存放到R个本地文件中的一个(后来每个文件都会指派一个Reduce任务)。

       master通知分配了Reduce作业的worker它负责的分区在什么位置。当Reduce worker把所有它负责的中间键值对都读过来后,先对它们进行Shuffle和排序,使得相同键的键值对聚集在一起。因为不同的键可能会映射到同一个分区也就是同一个Reduce作业(谁让分区少呢),所以排序是必须的。

       reduce worker遍历排序后的中间键值对,对于每个唯一的键,都将键与关联的值传递给reduce函数,reduce函数产生的输出会添加到这个分区的输出文件中。

       当所有的Map和Reduce作业都完成了,MapReduce函数调用返回用户程序的代码。

       所有执行完毕后,MapReduce输出放在了R个分区的输出文件中(分别对应一个Reduce作业)。用户通常并不需要合并这R个文件,而是将其作为输入交给另一个MapReduce程序处理。整个过程中,输入数据是来自底层分布式文件系统(GFS)的,中间数据是放在本地文件系统的,最终输出数据是写入底层分布式文件系统(GFS)的。而且我们要注意Map/Reduce作业和map/reduce函数的区别:Map作业处理一个输入数据的分片,可能需要调用多次map函数来处理每个输入键值对;Reduce作业处理一个分区的中间键值对,期间要对每个不同的键调用一次reduce函数,Reduce作业最终也对应一个输出文件。

     

    二.map函数和reduce函数

       map函数和reduce函数是交给用户实现的,这两个函数定义了任务本身。

    • map函数:接受一个键值对(key-value pair>),产生一组中间键值对。MapReduce框架会将map函数产生的中间键值对里键相同的值传递给一个reduce函数。
    • reduce函数:接受一个键,以及相关的一组值,将这组值进行合并产生一组规模更小的值(通常只有一个或零个值)。

       统计词频的MapReduce函数的核心代码非常简短,主要就是实现这两个函数。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15

     


    map(String key, String value):
    // key: document name
    // value: document contents
    for each word w in value :
    EmitIntermediate(w, "1");

    reduce(String key, Iterator values):
    // key: a word
    // values: a list of counts
    int result = 0;
    for each v in values :
    result += ParseInt(v);
    Emit(AsString(result));

       在统计词频的例子里,map函数接受的键是文件名,值是文件的内容,map逐个遍历单词,每遇到一个单词w,就产生一个中间键值对<w, "1">,这表示单词w咱又找到了一个。

       MapReduce将键相同(都是单词w)的键值对传给reduce函数,这样reduce函数接受的键就是单词w,值是一串"1"(最基本的实现是这样,但可以优化),个数等于键为w的键值对的个数,然后将这些"1"累加就得到单词w的出现次数。最后这些单词的出现次数会被写到用户定义的位置,存储在底层的分布式存储系统(GFS或HDFS)。 

    三.应用举例

       还是以WordCount程序为例,假设有三台DataNode,每台DataNode有不一样的数据,如下表格所示:   

    DataNode1

    DataNode2

    how do you do

    how old are you

     经过Map函数后,生成以下键值对:

    DataNode1

    DataNode2

    how

    do

    you

    do

         1

         1

         1

         1

    how

    old

    are

    you

    1

    1

    1

    1

       然后按照key值排序,变成以下键值对:

    DataNode1

    DataNode2

    do

    do

    how

    you

    1

    1

          1

          1

    are

    how

    old

    you

    1

    1

    1

    1

                 如果有Combiner函数的话,则把相同的key进行计算;

    DataNode1

    DataNode2

    do

    how

    you

         2

         1

         1

    are

    how

    old

    you

    1

    1

    1

    1

       如果有Partition函数的话,则进行分区,分几个区就有几个Reducer同时进行运算,然后就会生成几个不一样的结果文件;默认只有一个Reducer进行工作。

       这里先讲一个Reducer的情况,数据先从2个DataNode中Copy过来,然后Merge到Reducer中去:

    Reducer

    do

    how

    you

    are

    how

    old

    you

    2

    1

    1

    1

    1

    1

    1

       然后对数据按照key进行排序(Sort),Copy,Merge,Sort过程统称为Shuffle过程:

    Reducer

    are

    do

    how

    how

    old

    you

    you

    1

    2

    1

    1

    1

    1

    1

    然后数据经过Reduce函数后,生成以下输出文件:

    Reducer

    are

    do

    how

    old

    you

    1

    2

    2

    1

    2

       到这里为止,整个MapReduce过程也就完成了。

       如果有多个Reducer的话,不同的是数据会分开Copy到不同的机器中,也就是分开计算,然后Copy到每个Reducer中的数据都会经过Merge,Sort,Reduce过程,最后每个Reducer都会生成一个结果文件。

  • 相关阅读:
    条理清晰的搭建SSH环境之整合Hibernate和Spring
    条理清晰的搭建SSH环境之整合Struts和Spring
    条理清晰的搭建SSH环境之添加所需jar包
    日志工具的使用
    ajax上传文件
    input标签添加上disable属性在移动端字体颜色不兼容的解决办法。
    复制复制复制复制复制复制复制
    animate旋转动画练习,css3形变练习
    canvas练习单个矩形形变
    canvas刮刮卡
  • 原文地址:https://www.cnblogs.com/larch18/p/4570111.html
Copyright © 2011-2022 走看看