为什么Spark比MapReduce快的原因

对于这个问题我先给出核心的答案,后面会进一步的扩展,有兴趣的可以去了解一下扩展内容。

核心答案

1、基于内存

学过Spark的应该都知道,Spark是基于内存进行数据处理操作的,而MapReduce则是基于磁盘进行数据处理。

MR的设计:将MapTask的输出作为中间结果,保存到文件当中,随后作为ReduceTask的输入。这样可以提高可靠性,减少了内存的占用,但是牺牲了性能。

Spark的设计:数据在内存当中进行交换(注意是交换,也就是转换算子的操作),但是内存可靠性不如磁盘,所以性能方面比MR要好。

这里需要补充说明一下。

MR只有两种操作:map和reduce;

Spark的操作分为两类:transform和action。Transform包括:map,filter, flatMap, mapPartitions, mapPartitionsWithIndex, sample, pipe, union, intersection,distinct, groupByKey, reduceByKey, sortByKey, join, cogroup, Cartesian, coalesce,repartition。Action包括:reduce, collect, count, take,first, takeSample, saveAsTextFile, saveAsSequenceFile, saveAsObjectFile, countByKey,foreach。

而Spark中transform的返回值都是新的RDD,只有执行action操作才会返回结果或者将RDD数据写道存储系统中。即transform操作都是“懒执行”,仅仅只会记录,到action的时候才会真正进行执行。

2、DAG有向无环图

Spark中具有DAG有向无环图,在这个过程中减少了shuffle以及落盘的次数。(快的根本原因)

DAG 相比MapReduce 在大多数情况下可以减少 shuffle 次数。Spark 的 DAGScheduler 相当于一个改进版的 MapReduce,如果计算不涉及与其他节点进行数据交换,Spark 可以在内存中一次性完成这些操作,也就是中间结果无须落盘,减少了磁盘 IO 的操作。但是,如果计算过程中涉及数据交换,Spark 也是会把 shuffle 的数据写磁盘的!有一个误区,Spark 是基于内存的计算,所以快,这不是主要原因,要对数据做计算,必然得加载到内存,Hadoop 也是如此,只不过 Spark 支持将需要反复用到的数据给 Cache 到内存中,减少数据加载耗时,所以 Spark 跑机器学习算法比较在行(需要对数据进行反复迭代)。Spark 基于磁盘的计算也是比 Hadoop 快。刚刚提到了Spark 的 DAGScheduler 是个改进版的 MapReduce,所以 Spark天生适合做批处理的任务。Hadoop 的 MapReduce 虽然不如 spark 性能好,但是 HDFS 仍然是业界的大数据存储标准。

补充说明一下shuffle

Hadoop中MapReduce 将处理流程划分为:map, spill, merge, shuffle, sort, reduce等阶段,shuffle是位于map和reduce中间的一个阶段。在 Spark 中,没有这样功能明确的阶段。Spark将用户定义的计算过程转化为一个被称作Job逻辑执行图的有向无环图(DAG),图中的顶点代表RDD,边代表RDD之间的依赖关系。再将这个逻辑执行图转化为物理执行图,具体方法是:从逻辑图后往前推算,遇到 ShuffleDependency 就断开,最后根据断开的次数n,将其化分为(n+1)个stage。每个 stage 里面 task 的数目由该 stage 最后一个 RDD 中的 partition 个数决定。因此,Spark的Job的shuffle数是不固定的。

3、粗粒度资源申请

这里简单区分一下粗粒度和细粒度的区别。

粗粒度:静态分配资源:在application 启动时前已经为其分配好了所需的资源,后续不需要再分配资源。

细粒度:按需、动态分配资源:task自己去申请资源,task完成后就立即回收资源。

由于Spark是粗粒度资源申请,所以只有在申请到了资源的情况下,才会执行application,在task执行的过程当中就不需要进行资源申请,task执行快。不过缺点就是不能使集群得到充分的利用。

举个例子:有1000个task,其中999个task已经完成了,1个task特别的慢,这样就相当于999个task的资源空闲浪费了。

而MapReduce是细粒度资源申请,当提交application的时候,task执行时,自己申请资源,自己释放资源,task执行完毕之后,资源立即会被释放,task执行的慢,application执行的相对比较慢。优点是集群资源得到充分利用,缺点是application执行的相对比较慢。

ok,以上就是spark比MR快的根本原因,下面就是一些拓展因素了。

拓展

1、MR进程 / Spark线程

虽然MR和Spark都会将Job拆分为多个Task,但是MR的task对应的是一个个的Java进程,而Spark则是对应的是线程,Spark上每个task的生命周期都比Hadoop更轻量级,当然也就更快了。

2、网络通信

Spark的网络通讯模块通过Java Native Interface转给原生的Netty来做,而不是像Hadoop那样,让Hadoop框架自己负担。这样,Spark实际上借助了Netty来提升了网络传输性能。前面说到的外部shuffle服务就是建立在这个模块之上的。

3、编程语言

虽然Hadoop和Spark都支持Java,但这次Spark主要是用Scala语言实现的。函数式编程语言不需要考虑死锁,因为它不修改变量,所以根本不存在"锁"线程的问题。不必担心一个线程的数据,被另一个线程修改,所以可以很放心地把工作分摊到多个线程,实现并发编程。因此,Scala的并行性明显优于面向对象的Java语言。Spark对于Scala的原生支持也是其优势之一。

最后说一下,如果在储备满足的情况下,同样的业务处理,优先选择spark来进行实现,这样对于统计分析的执行效率会有很大的提升。

你可能感兴趣的:(Spark,大数据,spark,大数据)