Spark现在已逐渐代替了MapReduce在Hadoop中的作用,解决了MapReduce在Hadoop2.0版本中的诸多不足之处。

  1. 减少磁盘IO
    1.1 MapReduce的map端输出的中间结果会存储在磁盘之中,reduce端再从 磁盘中读取中间结果,从而造成了大量的磁盘IO。然而Spark是基于内存的计算,运行map段的中间结果存储在内存中,从而避免了大量磁盘IO。此处涉及到RDD的持久化。
    1.2在MapReduce提交过程中,所有的资源包括Jar包等信息都会存储到HDFS的临时文件中,在各个节点运行时都需要进行下载,这同样会造成大量磁盘IO。而Spark的资源文件都存储在Driver的内存中,executor在执行时直接从内存中获取。
  2. 增加并行度
    所谓的增加并行度就是不同环境的执行顺序不同导致的。在MapReduce中,执行顺序是固定的,必须先经过map端获得中间结果才能进一步执行reduce端程序。而在Spark在,Spark把不同环节抽象成为Stage,因此运行时既可以串联执行又可以并行执行,从而提高了运行速度。
  3. 避免重复计算
    这一点与上一条有着相似的原因。因为运行可以非串联,所以当程序执行到某一步出现错误时,仅仅需要对该步骤进行重复计算,而不像MapReduce需要所有程序的重新计算。
  4. Shuffle的选择
    Spark中对于Shuffle的选择是可以根据算子来决定的,在不同需要的处理中可以选择Shuffle,也可以不选择走Shuffle;而在MapReduce中,Shuffle和Reduce是直接关联的,是没有选择余地的。因此Spark可以减少Shuffle的次数,从而增加运行速度。同时,由于Spark中Shuffle与排序进行了分离,Spark可以根据不同场景选择map端排序或者reduce端的排序,而MapReduce只有走Shuffle才会进行排序。
  5. 灵活的内存管理策略
    Spark的内存分为堆上的存储内存、堆外的存储内存、堆上的执行内存、堆外的执行内存。而执行内存和存储内存的边界性质是可以设置的,默认是软边界,即可以临时的进行转换,从而提高内存的利用率。
    另外,Spark提供的Tungsten实现了直接对操作系统的直接操作,减少了创建Java对象在堆中占用的内存
    Spark会给每个Task分配一个对应的任务内存管理器,对Task粒度的内存进行管理。Task的内存可以被多个算子进行使用,任务内存管理器对每个算子进行Task内存的分配与管理,因此Spark对内存有着更细粒度的管理。

基于以上原因,Spark的运行速度比MapReduce的运行速度快非常多,Spark官网上称,其运行速度能够达到MapReduce的100倍。