MapReduce计算模型二 MapReduce框架Hadoop应用(一)

以前写过关于Hadoop方面的MapReduce框架的文章MapReduce框架Hadoop应用(一) 介绍了MapReduce的模型和Hadoop下的MapReduce框架,此文章将进一步介绍mapreduce计算模型能用于解决什么问题及有什么巧妙优化。html

MapReduce到底解决什么问题?

MapReduce准确的说,它不是一个产品,而是一种解决问题的思路,可以用分治策略来解决问题。例如:网页抓取、日志处理、索引倒排、查询请求汇总等等问题。经过分治法,将一个大规模的问题,分解成多个小规模的问题(分),多个小规模问题解决,再统筹小问题的解(合),就可以解决大规模的问题。最先在单机的体系下计算,当输入数据量巨大的时候,处理很慢。如何可以在短期内完成处理,很容易想到的思路是,将这些计算分布在成百上千的主机上,但此时,会遇到各类复杂的问题,例如:并发计算、数据分发、错误处理、数据分布、负载均衡、集群管理与通讯等,将这些问题综合起来将是比较复杂的问题了,而Google为了方便用户使用系统,提供给了用户不多的接口,去解决复杂的问题。网络

    (1) Map函数接口:处理一个基于key/value(后简称k/v)的数据对(pair)数据集合,同时也输出基于k/v的数据集合。并发

    (2) Reduce函数接口:用来合并Map输出的k/v数据集合负载均衡

假设咱们要统计大量文档中单词出现的次数框架

  Map函数

    输入K/V:pair(文档名称,文档内容)oop

    输出K/V:pair(单词,1)post

  Reduce优化

    输入K/V:pair(单词,1)url

    输出K/V:pair(单词,总计数) 

  Map伪代码:

Map(list<pair($docName, $docContent)>){//若是有多个Map进程,输入能够是一个pair,不是一个list
        foreach(pair in list)
                foreach($word in $docContent)
                        print pair($word, 1); // 输出list<k,v>
}            

  Reduce伪代码:

Reduce(list<pair($word, $count)>){//大量(word,1)(即便有多个Reduce进程,输入也是list<pair>,由于它的输入是Map的输出)
    map<string,int> result;
        foreach(pair in list)
         if result.isExist($word)
             result[$word] += $count;          else              result[$word] = 1; foreach($keyin result) print pair($key, result[$key]); //输出list<k,v> }

  

  能够看到,R个reduce实例并发进行处理,直接输出最后的计数结果。须要理解的是,因为这是业务计算的最终结果,一个单词的计数不会出如今两个实例里。即:若是(a, 256)出如今了实例1的输出里,就必定不会出如今其余实例的输出里,不然的话,还须要合并,就不是最终结果。

  再看中间步骤,map到reduce的过程,M个map实例的输出,会做为R个reduce实例的输入。

  问题一:每一个map都有可能输出(a, 1),而最终结果(a, 256)必须由一个reduce输出,那如何保证每一个map输出的同一个key,落到同一个reduce上去呢?

    这就是“分区函数”的做用。分区函数是使用MapReduce的用户按所需实现的,决定map输出的每个key应当落到哪一个reduce上的函数。若是用户没有实现,会使用默认分区函数。为了保证每个reduce实例都可以差很少时间结束工做任务,分区函数的实现要点是:尽可能负载均衡,即数据均匀分摊,防止数据倾斜形成部分reduce节点数据饥饿。若是数据不是负载均衡的,那么有些reduce实例处理的单词多,有些reduce处理的单词少,这样就可能出现全部reduce实例都处理结束,最后等待一个须要长时间处理的reduce状况。

  问题二:每一个map都有可能输出多个(a, 1),这样就增大了网络带宽资源以及reduce的计算资源,怎么办?

    这就是“合并函数”的做用。有时,map产生的中间key的重复数据比重很大,能够提供给用户一个自定义函数,在一个map实例完成工做后,本地就作一次合并,这样将大大节约网络传输与reduce计算资源。合并函数在每一个map任务结束前都会执行一次,通常来讲,合并函数与reduce函数是同样的,区别是:合并函数是执行map实例本地数据合并,而reduce函数是执行最终的合并,会收集多个map实例的数据。对于词频统计应用,合并函数能够将:一个map实例的多个(a, 1)合并成一个(a, count)输出。

  问题三:如何肯定文件到map的输入呢?

    随意便可,只要负载均衡,均匀切分输入文件大小就行,不用管分到哪一个map实例都能正确处理

  问题四:map和reduce可能会产生不少磁盘io,将更适用于离线计算,完成离线做业。

相关文章
相关标签/搜索