谁能用单词计数的例子解释一下,为什么Spark会比Map Reduce快?
bafna的回答提供了内存方面的问题,但我想补充另外两个重要的事实:DAG和生态系统
- Spark使用"惰性求值"形成连续计算阶段的有向无环图(DAG)。通过这种方式,可以优化执行计划,例如最小化数据的变换。相反,这应该在MapReduce中通过调优每个MR步骤手动完成。(如果您熟悉RDBMS中的执行计划优化或Apache Tez的dag式执行,则更容易理解这一点)
- Spark生态系统已经建立了一个通用的组件堆栈来处理SQL, ML, Streaming, Graph Mining任务。但是在hadoop生态系统中,你必须安装其他包来完成这些单独的事情。
并且我想补充的是,即使你的数据对于主存来说太大,你仍然可以通过选择将数据持久化在磁盘上来使用spark。尽管这样做放弃了内存处理的优点,但您仍然可以从DAG执行优化中获益。
Quora上的一些有用的答案:这里和这里
我认为主要有三个原因。
主要的两个原因源于这样一个事实,即通常不会运行单个MapReduce作业,而是按顺序运行一组作业。
-
MapReduce的主要限制之一是它在运行每个作业后将完整的数据集持久化到HDFS。这是非常昂贵的,因为它会导致磁盘I/O数据集的三倍(用于复制)和类似数量的网络I/O。Spark对操作管道采取了更全面的看法。当一个操作的输出需要馈送到另一个操作时,Spark直接传递数据,而不写入持久存储。这是一个基于MapReduce的创新,来自于微软的Dryad论文,并不是Spark的原创。
-
Spark的主要创新是引入了一个内存缓存抽象。这使得Spark非常适合多个操作访问相同输入数据的工作负载。用户可以指示Spark在内存中缓存输入数据集,这样就不需要每次操作都从磁盘读取数据集。
-
如果Spark作业可以归结为单个MapReduce作业呢?在很多情况下,它们在Spark上比在MapReduce上运行得更快。Spark在这方面的主要优势是它可以更快地启动任务。MapReduce为每个任务启动一个新的JVM,加载jar、编译、解析配置XML等需要几秒钟的时间。Spark在每个节点上都运行一个执行器JVM,所以启动一个任务只是简单地向它创建一个RPC,并将一个Runnable传递给线程池,这需要花费个位数毫秒。
最后,可能值得一提的一个常见误解是,Spark在某种程度上完全运行在内存中,而MapReduce不是。事实并非如此。Spark的shuffle实现与MapReduce非常相似:每个记录在map端被序列化并写入磁盘,然后在reduce端被提取和反序列化。