[MR] MapReduce 总结、回顾与吐槽

1、Map&Reduce起源

MapReduce最先由Google提出,论文出处《DEAN, J., AND GHEMAWAT, S. MapReduce: Simplified data processing on large clusters.》,有兴趣的话能够去看看原文,固然也有翻译。这篇文章和Google的《Bigtable: A Distributed Storage System for Structured Data 》是同期的,是Google对外介绍自身大规模数据处理架构的论文。程序员

MapReduce受Lisp等函数式编程语言的Map 和 Reduce 语义启发,关于函数式编程语言,笔者了解的很少,关于其最主要的一点,是由程序运行时负责程序的调用、执行等,理解这一点很重要,由于由运行时负责调用是MR的核心,用户不须要去关心程序如何实现,它的规模多大,如何并行计算,多少个线程等等,用户只须要关心它们的语义,并按照语义去写Map函数和Reduce函数便可。redis

2、Map&Reduce

Map 也即映射,将一个或多个数据源映射为key-value样式sql

Reduce 也即概括,将Mapper的Key-value进行计算,以得出结果(同为key-value样式)数据库

整体而言很是好理解,但也所以容易引出个问题——Why?它与sql的select from where 有什么区别呢?Mapper也要筛选,Reducer也要计算。由于如今不少语言和数据库都引入了MR,这一问题变得尤其明显,原本它只是在大规模数据集群上计算,实在不理解还能用,“哦,框架就是这样”搪塞过去,如今不行了。编程

这个问题也困扰过我,如今个人理解是一点——交集。不少数据会符合一堆规则,若是单独的按照这些规则,一个一个挑出来,会形成重复计算,重复IO——不少时候符合条件A的数据也符合条件B,若是采用相似先计算选出选A,再选B的方式,则会有2次IO访问或是重复计算,浪费了算力(天然也省了内存),但当数据量大到必定的程度,节省下来的内存便进入长尾效应,并且对计算速度的拖累也更大,综合考虑下来,MR先使用Mapper无脑选候选数据,再使用Reducer计算更符合效率和成本。安全

3、Hadoop的Map Reduce。

关于DFS——Distributed File System.分布式文件系统,是Hadoop HDFS 的核心,也即基础设施,在面对大规模数据时,有这样2点重点,一是,省钱,二是,安全。对于这点Google提出的观点是,假设我买出错率很高的硬盘,1/1000,那么当我有3台这样的硬盘,它们同时出错的几率是多少呢?1/1000*1/1000*1/1000=1/1000000000,变得可接受了,并且廉价硬盘也带来了成本的降低,这样的文件系统就能够做为大数据的基础设施。架构

Hadoop(Hive)的MR是创建在HDFS之上的,原理也很是简单粗暴,读入文件,而后借助MR框架,去大规模并行计算。Now,MR理论上能够接受任何输入,但本着开箱即用的道理,绝大部分人仍是会选择从文件中读取,而后进行计算,这样的话,瓶颈就会在IO上面,并行计算的算力也没被解放开来。app

想要MR为你的计算实时服务,你就须要不少Wrapper从你的库中获取数据源,或者加速文件的读取,因此后面Hadoop萌生出那么多框架,也是有缘由的。框架

同时提到这句话,笔者注意到的一点是,在Google BigTable 论文中提到的Big Table是支持MR的,在其论文中有这样一句话编程语言

Bigtable can be used with MapReduce [12], a framework for running large-scale parallel computations developed at Google. We have written a set of wrappers that allow a Bigtable to be used both as an input source
and as an output target for MapReduce jobs.

后续Hadoop的山寨版——Hbase,虽然也支持,不过貌似效率不高,更多的仍是用Hive进行使用,并且在程序中,基本仍是对HDFS的直接操做。对于Hbase而言,反而更像是绕了远路,HDFS上的HFile读取,而后到Hbase,再传到Mapper里面,性能怎么样更多的仍是看你,或者Hbase的优化,由于这下连文件都看不到了。Google也不傻,既然提了这一说,那么BigTable底层实现和Hbase的区别,相比是很大的。

回顾完上面这些,不难发现,Hadoop,起码早期版本,就是一个空荡的平台,这也为后续一堆框架的提出埋下了伏笔。

4、MongoDB的MapReduce

提到MongoDB,这个后起之秀,就想起了一篇文章,《一个时代的终结——大数据已死》

Hadoop还面临这样的挑战:NoSQL数据库和对象存储提供商在解决Hadoop最初旨在帮助解决的部分存储和管理难题方面取得了进展。随着时间的推移,在Hadoop上支持业务连续性面临挑战,加上支持实时、地理空间及其余新兴的分析使用场合方面缺少灵活性,这使得Hadoop面对海量数据时很难在批处理以外大有做为。

我的以为文章写的仍是不错的,每一个新兴技术的出现都必将经历一波炒做,再到冷却,直至它做为广大技术栈中不起眼(基础)的一隅,凡事总要经历个过程,大数据已死是失去了热度,它已做为基础能力,再也不适合被大书特书。

回到MR上面来,笔者目前的项目呢,也是烂大街的Hadoop,对于MR的使用能够说是反面教材了,对数据集的中间结果处理使用了大量的 temp文件。并且还使用的是最简单最低效的TextFormat,每次mr都有大量的parse,做为程序员脑中的基础概念,关于程序的性能主要就几点,一个是IO,一个是算力(Taraflops),减小IO和没必要要的计算是时刻记住的重点,而这项目能够说2点禁忌全占了。而我若是想改,其实不光是改MR的逻辑,还要改HDFS里文件的存储方式,这样一来以新版和旧版为分界线,就须要一个Adapter来作老数据的读取……

那这样一来问题其实很明显,Hadoop自己就有纷繁复杂的技术栈, Hive,Spark,Hbase,Accumulo,Kylin,Storm ……要保证项目组的每个人深入理解这一堆技术栈,非但要调研成本,并且一旦换需求了,是否是还要对应改动呢?并且为了知足一些实时性的需求,还不得不从Hive MR到HBase,再入redis以提供大规模低时延调用。对于不少时候,只想要使用MR而已,又何苦这么麻烦呢。

在这种状况下,像MongoDB这样的库就提供了一个折中的办法,它不支持超大规模数据量的分析,这种状况下性能堪忧,可是对于大规模(SQL已经自闭)的程度仍是OK的,经过MongoDB 的MR,咱们仍然能借助MR思惟去处理大规模数据,若是不是长期存储的类型,MongoDB给出的方案反倒更为经济。

5、其余语言实现的MapReduce

(一)、 Java

Java自1.8以后引入了Stream API,Map和Ruduce也做为同期被引入,与Hadoop的MR不一样,它只能做为 Collection 接口下的方法,并不支持对每一个Key,value进行计算,而只能得出一个结果。而它的重点在于,若是使用了 parallelStream() ,便能轻松地执行并行化计算。

List<Integer> source=new ArrayList<>();
source.add(1);
source.add(2);
Optional<Integer> sum=source.stream().map(new Function<Integer, Integer>() {
    @Override
    public Integer apply(Integer t) {
        return t+1;
    }
}).reduce(new BinaryOperator<Integer>() {
            
    @Override
    public Integer apply(Integer t, Integer u) {
        return t+u;
    }
});
System.out.println(sum.get());

 

(二)、Javascript

待续。

相关文章
相关标签/搜索