1. IO操作

Spark是基于内存的计算,而Hadoop是基于磁盘的计算;Spark是一种内存计算技术。所谓的内存计算技术也就是缓存技术,把数据放到缓存中,减少cpu磁盘消耗。Spark和Hadoop的根本差异是多个任务之间的数据通信问题:Spark多个任务之间数据通信是基于内存,而Hadoop是基于磁盘。Hadoop每次shuffle操作后,必须写到磁盘,而Spark在shuffle后不一定落盘,可以cache到内存中,以便迭代时使用。如果操作复杂,很多的shufle操作,那么Hadoop的读写IO时间会大大增加。多个任务之间的操作也就是shuffle过程,因为要把不同task的相同信息集合到一起,这样内存的速度要明显大于磁盘了。

  MapReduce每次shuffle都必须写到磁盘中,而Spark的shuffle不一定写到磁盘中,而是可以缓存到内存中,
  以便后续的其他迭代操作时直接使用。这样一来,如果任务复杂,需要很多次的shuffle才能完成,
  那么Hadoop读写磁盘文件时花费在IO上的时间就会大大增加。
  比如:  select name,age from (select * from user where age >30 and age <40)
  
  2. shuffer机制
  
  通常每次MapReduce都会有一次shuffer;
  而Spark基于RDD提供了丰富的算子操作,简单来说,spark遇到宽依赖才会出现shuffer。消除了冗余的MapReduce阶段
  
  3. jvm优化

Hadoop每次MapReduce操作,启动一个Task便会启动一次JVM,基于进程的操作。而Spark每次MapReduce操作是基于线程的,只在启动Executor是启动一次JVM,内存的Task操作是在线程复用的。 
  mapreduce的任务它是以进程的方式运行在yarn集群中,比如一个job有1024个MapTask,
  这个时候就需要开启1024个进程去处理这个1024个task,可是启动一个task便会启动一次JVM。
  spark的任务它是以线程的方式运行在进程中,只在启动Executor进程时启动一次JVM。每次执行一个task,
  都是复用Executor进程中的线程(Executor中维护着一个线程池)。JVM的每次启动,
  都将会花费几秒甚至是十几秒的时间.如果task多了,基于进程的MR便会频繁的启动JVM,也就花费了大量启动JVM的时间。
  但是也有例外,像select month_id,sum(salas) from T group by month_id这样的查询,只发生了一次shuffle操作(group by),
  Spark需要创建线程池,此时,Hive HQL的运行时间也许比Spark还要块。 

  综上所述:Spark快主要是因为它对MapReduce操作的优化以及对JVM使用的优化.

  但Spark快并不是绝对的,在某些情况下,也有MapReduce比Spark快的情况。