Spark使用“惰性评估”来形成连续计算阶段的有向无环图(DAG)。这样,执行计划可以进行优化,例如最小化数据传输。相比之下,在MapReduce中需要通过调整每个MR步骤来手动完成此操作。(如果您熟悉RDBMS中的执行计划优化或Apache Tez的DAG式执行,则更容易理解此点) Spark生态系统已经建立了一个多功能组件堆栈来处理SQL、ML、Streaming、Graph Mining任务。但在Hadoop生态系统中,您必须安装其他软件包来完成这些单独的任务。 我想要补充一点的是,即使您的数据太大而无法放入内存,您仍然可以选择将其持久化到磁盘上并使用 Spark 进行处理。虽然这样做会失去内存处理的优势,但仍然可以从DAG执行优化中受益。 一些关于Quora的信息性回答: 这里 和 这里。
我认为有三个主要原因。主要的两个原因源于一个事实,通常情况下,人们不运行单个MapReduce作业,而是一系列的作业。1. MapReduce的主要限制之一在于,每次运行作业后都会将完整数据集持久化到HDFS。这非常昂贵,因为它会产生三倍(复制)数据集大小的磁盘I/O和类似数量的网络I/O。Spark采用更全面的操作流程视角。当一个操作的输出需要输入到另一个操作中时,Spark直接传递数据而不写入持久化存储。这是来自Microsoft的Dryad论文对MapReduce的革新,也是Spark的特色之一。2. Spark的主要创新之一是引入了内存缓存抽象。这使得Spark非常适合需要多个操作访问相同输入数据的工作负载。用户可以指示Spark将输入数据集缓存在内存中,以便每次操作时无需从磁盘读取。3. 那么针对只有一个MapReduce作业的Spark作业呢?在许多情况下,这些作业在Spark上比在MapReduce上运行得更快。Spark在这里的主要优势是可以更快地启动任务。MapReduce为每个任务启动一个新的JVM,这可能需要几秒钟时间来加载JAR文件、JIT编译、解析配置XML等。Spark在每个节点上保持一个执行器JVM运行,因此启动任务只需向其发出RPC并将可运行对象传递给线程池即可,这需要不到十毫秒的时间。最后,一个常见的误解值得一提,就是Spark完全在内存中运行,而MapReduce则不是。这显然不是事实。Spark的Shuffle实现非常类似于MapReduce:在Map端将每个记录序列化并写入磁盘,然后在Reduce端获取并反序列化。