简介
基于内存计算的大数据并行计算框架;一个可用于大规模数据快速处理的快速、通用引擎。为Apache分布式计算三大框架[hadoop, Spark, Storm]之一。
Spark目的:使数据分析更快,不仅运行速度快,也要能快速、容易地编写程序。为了程序更快,Spark提供了内存运算,减少了迭代计算时的IO开销。
由于Hadoop中MapReduce存在诸多缺陷,Spark可以解决。
特点
- 运算速度快:使用先进的DAG(Directed Acyclic Graph,有向无环图)执行引擎,以支持循环数据流与内存计算,基于内存的执行速度可比Hadoop MapReduce快上百倍,基于磁盘的执行速度也能快十倍;
- 容易使用:Spark支持使用Scala、Java、Python和R语言进行编程,简洁的API设计有助于用户轻松构建并行程序,并且可以通过Spark Shell进行交互式编程;
- 通用性:Spark提供了完整而强大的技术栈,包括SQL查询、流式计算、机器学习和图算法组件,这些组件可以无缝整合在同一个应用中,足以应对复杂的计算;
- 运行模式多样:Spark可运行于独立的集群模式中,或者运行于Hadoop中,也可运行于Amazon EC2等云环境中,并且可以访问HDFS、Cassandra、HBase、Hive等多种数据源。
优势
HADOOP problem:- hadoop 本身诸多缺陷,最主要:MapReduce计算模型延迟过高,无法胜任实时、快速计算的需求,只适用离线批处理;
- 表达能力有限:所有计算必须转成Map和Reduce;
- 磁盘IO开销大:每次执行都需从磁盘读取数据,计算完成后需要将中间结果写入磁盘
- 延迟高:一次计算可能需要分解成一系列按顺序执行的MapReduce,任务之间的衔接由于涉及到IO开销,延迟高;必须等到上一个任务完成才能执行下一个任务
Spark 优势: - Spark计算也是MapReduce,但不局限与Map和Reduce,还提供了多种数据集操作类型,编程模型比MapReduce更灵活
- 提供了内存计算,中间结果直接存内存
- 基于DAG的任务调度执行机制,要优于MapReduce的迭代执行机制
最大的特点:将计算数据,中间结果都存储在内存中,减少IO开销。
MapReduce要写不少底层代码;Spark封装了API。Spark主要用了替代Hadoop中MapReduce计算模型。
生态系统
实际应用中,大数据处理主要包括:
- 复杂的批量数据处理:时间跨度长在数十分钟到数小时之间;
- 基于历史数据的交互式查询:时间跨度在数十秒到数分钟之间;
- 基于实时数据流的数据处理:时间跨度通常在数百毫秒到数秒之间。
可以利用Hadoop MapReduce来进行批量数据处理,可以用Impala来进行交互式查询(Impala与Hive相似,但底层引擎不同,提供了实时交互式SQL查询),对于流式数据处理可以采用开源流计算框架Storm。
多个软件难以统一;Spark的设计遵循:一个软件栈满足不同应用场景,既能提供内存计算框架,也可支持SQL及时查询,实时流式计算,机器学习和图计算。Spark可以部署在资源管理器YARN之上,提供一站式的大数据解决方案。因此,Spark所提供的生态系统足以应对上述三种场景,即同时支持批处理、交互式查询和流数据处理。
Spark的生态系统: Spark Core、Spark SQL、Spark Streaming、MLLib和GraphX。
- Spark Core:Spark Core包含Spark的基本功能,如内存计算、任务调度、部署模式、故障恢复、存储管理等。Spark建立在统一的抽象RDD之上,使其可以以基本一致的方式应对不同的大数据处理场景;通常所说的Apache Spark,就是指Spark Core;
- Spark SQL:Spark SQL允许开发人员直接处理RDD,同时也可处理HIVE,HBase等外部数据。Spark SQL特点:能够统一处理关系表和RDD。可使用SQL命令进行查询。
- Spark Streaming:Spark Streaming支出高吞吐量、可容错的实时流数据处理:核心是将流式计算分解成一系列短小的批处理作业。
- MLlib(机器学习):MLlib提供; 常用的机器学习算法实现,聚类,分类。回归、协同过滤。
- Graphx(图计算): Graphx是Spark用于图计算的API。
运行架构
基本概念
- RDD:是弹性分布式数据集(Resilient Distributed Dataset),是分布式内存的一个抽象概念,提供了一种高度受限的共享内存模型
- DAG: Distributed Acyclic Graph(有项无环图),反映了RDD之间的依赖关系
- Executor: 运行在工作节点(Worker Node)上的一个进程,负责运行任务,并为应用程序存储数据。
- 应用:用户编写的Spark应用程序
- 任务: 运行在Executor上的工作单元
- 作业:一个作业包含多个RDD及作用于相应RDD上的各种操作;
- 阶段:是作业的基本调度单位,一个作业分为多组任务,每组任务被称为“阶段”,也是”任务集”
[应用[作业[阶段[任务…]…]…]]
架构设计
如图9-5所示,Spark运行架构包括集群资源管理器(Cluster Manager)、运行作业任务的工作节点(Worker Node)、每个应用的任务控制节点(Driver)和每个工作节点上负责具体任务的执行进程(Executor)。其中,集群资源管理器可以是Spark自带的资源管理器,也可以是YARN或Mesos等资源管理框架。
与Hadoop MapReduce计算框架相比,Spark所采用的Executor有两个优点:一是利用多线程来执行具体的任务(Hadoop MapReduce采用的是进程模型),减少任务的启动开销;二是Executor中有一个BlockManager存储模块,会将内存和磁盘共同作为存储设备,当需要多轮迭代计算时,可以将中间结果存储到这个存储模块里,下次需要时,就可以直接读该存储模块里的数据,而不需要读写到HDFS等文件系统里,因而有效减少了IO开销;或者在交互式查询场景下,预先将表缓存到该存储系统上,从而可以提高读写IO性能。如下图:
总体而言,如下图所示,在Spark中,一个应用(Application)由一个任务控制节点(Driver)和若干个作业(Job)构成,一个作业由多个阶段(Stage)构成,一个阶段由多个任务(Task)组成。当执行一个应用时,任务控制节点会向集群管理器(Cluster Manager)申请资源,启动Executor,并向Executor发送应用程序代码和文件,然后在Executor上执行任务,运行结束后,执行结果会返回给任务控制节点,或者写到HDFS或者其他数据库中。
Spark运行基本流程
如下图所示,Spark的基本流程:
(1)当一个Spark应用被提交时,首先需要为这个应用构建起基本的运行环境,即由任务控制节点(Driver)创建一个SparkContext,由SparkContext负责和资源管理器(Cluster Manager)的通信以及进行资源的申请、任务的分配和监控等。SparkContext会向资源管理器注册并申请运行Executor的资源;
(2)资源管理器为Executor分配资源,并启动Executor进程,Executor运行情况将随着“心跳”发送到资源管理器上;
(3)SparkContext根据RDD的依赖关系构建DAG图,DAG图提交给DAG调度器(DAGScheduler)进行解析,将DAG图分解成多个“阶段”(每个阶段都是一个任务集),并且计算出各个阶段之间的依赖关系,然后把一个个“任务集”提交给底层的任务调度器(TaskScheduler)进行处理;Executor向SparkContext申请任务,任务调度器将任务分发给Executor运行,同时,SparkContext将应用程序代码发放给Executor;
(4)任务在Executor上运行,把执行结果反馈给任务调度器,然后反馈给DAG调度器,运行完毕后写入数据并释放所有资源。
总体而言,Spark运行架构具有以下特点:
(1)每个应用都有自己专属的Executor进程,并且该进程在应用运行期间一直驻留。Executor进程以多线程的方式运行任务,减少了多进程任务频繁的启动开销,使得任务执行变得非常高效和可靠;
(2)Spark运行过程与资源管理器无关,只要能够获取Executor进程并保持通信即可;
(3)Executor上有一个BlockManager存储模块,类似于键值存储系统(把内存和磁盘共同作为存储设备),在处理迭代计算任务时,不需要把中间结果写入到HDFS等文件系统,而是直接放在这个存储系统上,后续有需要时就可以直接读取;在交互式查询场景下,也可以把表提前缓存到这个存储系统上,提高读写IO性能;
(4)任务采用了数据本地性和推测执行等优化机制。数据本地性是尽量将计算移到数据所在的节点上进行,即“计算向数据靠拢”,因为移动计算比移动数据所占的网络资源要少得多。而且,Spark采用了延时调度机制,可以在更大的程度上实现执行过程优化。比如,拥有数据的节点当前正被其他的任务占用,那么,在这种情况下是否需要将数据移动到其他的空闲节点呢?答案是不一定。因为,如果经过预测发现当前节点结束当前任务的时间要比移动数据的时间还要少,那么,调度就会等待,直到当前节点可用。