一、Spark简介

spark是由伯克利于2009年开发,是基于内存计算的大数据并行计算框架,可用于构建大型的、低延迟的数据分析应用程序。2013年,Spark加入Apache孵化器项目。如今已成为Apache软件基金会最重要的三大分布式计算系统开源项目之一(即Hadoop、Spark、Storm)。2014年打破了Hadoop保持的基准排序(Sort Benchmark)纪录。

特点

  1. 运行速度快(相比hadoop)
  2. 易用性:支持scala、java、python等多种语言; API简单易用;可以用spark shell交互
  3. 通用性:技术栈完整强大;有SQL查询、流计算、机器学习算法、图算法组件,无缝对接
  4. 部署灵活:可以独立集群运行,也可结合hadoop

对比hadoop

  1. 运行更快:spark基于内存运算,中间结果在内存;hadoop基于磁盘
  2. 运行模式更灵活;不仅用mapreduce模式,还有其它
  3. 调度机制更优:基于DAG的任务调度机制,优于MapReduce的迭代执行机制

spark生态

Spark的生态系统主要包含了Spark Core、Spark SQL、Spark Streaming、MLLib和GraphX 等组件;Spark生态系统已经成为伯克利数据分析软件栈BDAS(Berkeley Data Analytics Stack)的重要组成部分。BDAS架构如下

Spark进行机器学习的流程 spark入门_依赖关系

二、Spark运行架构

架构设计

Spark运行架构包括集群资源管理器(Cluster Manager)、运行作业任务的工作节点(Worker Node)、每个应用的任务控制节点(Driver)和每个工作节点上负责具体任务的执行进程(Executor)

架构图如下:

Spark进行机器学习的流程 spark入门_hadoop_02

spark运行基本流程

  1. spark submit提交应用程序后,由任务控制节点(Driver)为改应用创建一个SparkContext;SparkContext负责和资源管理器(Cluster Manager)的通信以及进行资源的申请、任务的分配和监控等。
  2. SparkContext会向Cluster Manager注册并申请运行Executor的资源;然后Cluster Manager会创建一个Executor进程(每个应用都有自己专属的Executor进程,并且该进程在应用运行期间一直驻留);Executor运行情况定期汇报给Cluster Manager
  • SparkContext根据RDD的依赖关系构建DAG图,DAG图提交给DAG调度器(DAGScheduler)进行解析
  • DAGScheduler将DAG图分解成多个“阶段”(每个阶段都是一个任务集),并且计算出各个阶段之间的依赖关系,然后把一个个“任务集”提交给底层的任务调度器(TaskScheduler)进行处理
  • Executor进程向SparkContext申请任务,TaskScheduler将任务分发给Executor进程运行,同时,SparkContext将应用程序代码发放给Executor进程
  1. 任务在Executor上运行,把执行结果反馈给TaskScheduler,然后反馈给DAG调度器,运行完毕后写入数据并释放所有资源。
    流程图如下:

三、RDD运行原理

1.设计缘起

  • 实际中许多迭代式算法(机器学习、图计算)等需要中间结果给后续计算,但MapReduce模式将中间结果保存到HDFS中,有大量磁盘IO、数据复制等开销。
  • 谷歌09年提出的Pregel图计算框架 将结果保存到内存中,但只支持特定的计算模式(不通用
  • RDD应运而生。提供一个抽象的数据架构

2.RDD概念

  • RDD是弹性分布式数据集(Resilient Distributed Dataset)的简称,是一个抽象概念(类比cache中的block),是spark运算的最基本单元,其实是内存中的一部分
  • 一个RDD是多个分区构成的集合,每个分区是内存上的一个数据集片段
  • 一个RDD的多个分区可以分布在集群的不同节点上,这样可以并行计算
  • RDD是只读的记录分区的集合,不能直接修改
  • 只能基于稳定的物理存储中的数据集来创建RDD,或者通过在其他RDD上执行确定的转换操作(如map、join和groupBy)而创建得到新的RDD
  • RDD提供了一组丰富的操作以支持常见的数据运算,分为“行动”(Action)和“转换”(Transformation)两种类型,前者用于执行计算并指定输出的形式,后者指定RDD之间的相互依赖关系
  • 转换操作(比如map、filter、groupBy、join等);行动操作(比如count、collect等)

3.RDD执行过程

  1. 输入数据,创建RDD
  2. RDD每次经过一个Transformation操作,都会产生不同的RDD,供给下一个Transformation使用
  3. RDD遇到Action操作就会开始计算
  • 注意:RDD的执行过程中,真正的计算发生在RDD的“行动”操作,对于“行动”之前的所有“转换”操作,Spark只是记录下“转换”操作应用的一些基础数据集以及RDD生成的轨迹,即相互之间的依赖关系,而不会触发真正的计算。

4.RDD之间的依赖关系

每个RDD有多个分区,根据父RDD分区到子RDD分区的映射类型分为窄依赖和宽依赖。

  • 窄依赖:一个父RDD的分区对应于一个子RDD的分区,或多个父RDD的分区对应于一个子RDD的分区
  • 宽依赖: 存在一个父RDD的一个分区对应一个子RDD的多个分区
  • 如果父RDD的一个分区只被一个子RDD的一个分区所使用就是窄依赖,否则就是宽依赖。窄依赖典型的操作包括map、filter、union等,宽依赖典型的操作包括groupByKey、sortByKey等

如图所示

Spark进行机器学习的流程 spark入门_依赖关系_03

5.RDD运行过程

根据RDD之间不同依赖关系划分阶段

  • Spark通过分析各个RDD的依赖关系生成了DAG,再通过分析各个RDD中的分区之间的依赖关系来决定如何划分阶段
  • 在DAG中进行反向解析,遇到宽依赖就断开,遇到窄依赖就把当前的RDD加入到当前的阶段中
  • 将窄依赖尽量划分在同一个阶段中,可以实现流水线计算

RDD运行过程如图所示:

Spark进行机器学习的流程 spark入门_spark_04