1.Spark基本概念
Spark是一种基于内存计算的大数据并行计算框架,最早是由加州大学伯克利分校开发,现已经成为Apche顶级开源项目,其作为MapReduce 的替代方案,兼容HDFS、Hive等分布式存储层,相对于MapReduce其具有以下优点:
- 基于内存计算,避免了大量IO操作,速度快
- 秉持移动计算优于移动数据的理念,大大减少了文件的传输代价
- 更好的容错性
- 提供了实时的流处理功能
- 简单易用
- 强大的社区支持
- 支持多语言编程接口
2.Spark 与 Hadoop
Spark作为hadoop大数据处理体系中的一员,最新的架构基于hadoop2.0,如下图所示:
Hadoop2.0的架构分为三层,最底层为分布式存储系统即HDFS,中间层为资源管理系统,广泛使用Yarn,最上层为分布式计算框架层,在这一层可以存在各种各样的并行计算框架,比如MapReduce、Spark等,其实在hadoop1.0时是没有资源管理系统这一层的,在老版本中,是由资源管理模块来对计算资源进行管理的,不同的分布式计算框架对应不同的资源管理模块,MapReduce 对应MapReduce的资源管理模块,Spark对应Spark的资源管理模块,随着大数据处理技术的不断发展,出现了各式各样的计算框架,为了使Hadoop更好的支持这些计算框架,因此2.0中提出了资源管理系统层,所有计算框架的资源统一由资源管理系统来分配管理,从而可以更好的支持不断推陈出新的计算框架;
3.Spark生态系统
Spark主要提供了上图所示的几部分功能:
- SparkCore :基于RDD提供了丰富的操作接口,更加灵活的处理批处理作业
- Spark SQL:兼容Hive的接口HQL,提供更快速度的SQL查询
- Spark Streaming:将流式计算分解为短批处理作业,支持流式处理作业
- GraphX:基于Spark的图处理框架,提供图构建及图转换功能
- MLlib: 构建在Spark上的机器学习算法库,支持常见的推荐算法、聚类算法
4.Spark RDD
在Spark中最为关键的当属RDD(Resilient Distributed DataSets) ,全称:弹性分布式数据集,RDD存储在内存中,因此大大减少了像MapReduce中的文件IO操作,提高了运算速度,RDD来源只有两个途径:
- 来自于内存集合和外部存储系统
- 来自于其他RDD,比如通过转换操作:map、filter、join等
RDD具有以下五种特性: - 分区属性:每个RDD由若干个partition构成
- 依赖关系:RDD之间是具有依赖关系的,下一小节会详细介绍
- 分区单位计算:RDD中的计算都是以分区为单位的,即每个运算作用于一个分区中的所有元素
- 分区函数:分为哈希分区函数及区域分区函数
- 优先位置:Spark秉承移动数据不如移动计算的理念,在生成运算任务时优先会将计算放在数据所在的节点上,尽量避免数据的传输开销
4.1 RDD 依赖关系
RDD依赖关系分为两种,窄依赖与宽依赖,两者定义如下:
- 窄依赖:是指每个父RDD的一个Partition最多被子RDD的一个Partition所使用,例如map、filter、union等操作都会产生窄依赖;
-
宽依赖:是指一个父RDD的Partition会被多个子RDD的Partition所使用,例如groupByKey、reduceByKey、sortByKey等操作都会产生宽依赖;
依赖关系是Spark切分任务阶段的依据;
RDD之间的依赖关系是Spark拆分任务阶段的依据,后面会详细讲解;
4.2 RDD操作
RDD操作可简单分为两类,一类为Transformation操作,另一类为Action操作,两者区别如下:
可以简单的认为Transformation操作只是建立了RDD之间的逻辑关系,并不会真正触发运算,只有遇到Action操作后才会真正触发作业的提交,一个spark程序会穿插着Transformation操作与Action操作,Action才会得到最终的结果;
5.Spark运行模式及原理
如图中所示:一个Spark程序可从逻辑上拆分为Driver程序与Worker程序,Driver程序在运行过程中会创建SparkContext,SparkContext是整个程序的入口,SparkContext在初始化过程中会创建DAGScheduler和TaskScheduler,分别负责作业调度和任务调度,这两个模块是Spark程序切分作业及任务调度最为核心的模块,后面小节会进行详细介绍,SparkContext通过资源管理模块与Executor通讯,在SparkContext申请到计算资源后,会将任务分配到具体的Executor上运行;
5.1 Spark调度管理
Spark调度相关基本概念:
- Task(任务):单个分区数据集上最小的处理流程单元
- TaskSet(任务集):一组关联的并且无依赖关系的任务集合
- Stage(调度阶段):一个任务集合对应一个调度阶段
- Job(作业):由一个或多个调度阶段组成
-
Application(应用程序):由一个或多个作业组成
其之间的关系可用下图表示:
Spark调度管理主要由DAGScheduler和TaskScheduler负责:
- 作业调度-DAGScheduler– 任务的规划者
- 任务调度-TaskScheduler– 任务的执行者
SparkContext初始化过程中会生成DAG图,DAG图表示了整个任务中RDD之间的逻辑关系,DAGScheduler会从该图的终结点向前开始遍历,当遇到宽依赖时会将当前遍历的RDD操作划归于一个调度阶段(即一个任务集合),然后再进行下一阶段的遍历,最后将由若干个调度阶段组成的作业提交给TaskScheduler,作业的执行是按照调度阶段顺序有序执行的,只有前一阶段执行成功后才会进行下一阶段的调度,当任务集合提交给TaskScheduler后,任务集管理模块会创建TaskSetManager实例来对该任务集进行管理,申请到资源后任务开始执行,任务执行结束后结果会反馈给TaskScheduler,任务集任务执行情况同样会反馈给DAGScheduler,当前阶段任务集执行成功后会依次进行下一阶段任务集的调度;
6.Spark任务监控
Spark自带了UI界面来向用户展示作业的执行情况;通过UI界面可以查看Job,Stage,Storge等的执行情况;