【导读:数据是二十一世纪的石油,蕴含巨大价值,这是·情报通·大数据技术系列第[71]篇文章,欢迎阅读和收藏】

1 基本概念

Spark 架构采用了分布式计算中的 Master-Slave 模型。 Master 是对应集群中的含有 Master 进程的节点, Slave 是集群中含有 Worker 进程的节点。 Master 作为整个集群的控制器,负责整个集群的正常运行; Worker 相当于计算节点,接收主节点命令与进行状态汇报; Executor 负责任务的执行; Client 作为用户的客户端负责提交应用, Driver 负责控制一个应用的执行。

Spark 集群部署后,需要在主节点和从节点分别启动 Master 进程和 Worker 进程,对整个集群进行控制。在一个 Spark 应用的执行过程中, Driver 和 Worker 是两个重要角色。 Driver 程序是应用逻辑执行的起点,负责作业的调度,即 Task 任务的分发,而多个 Worker 用来管理计算节点和创建 Executor 并行处理任务。在执行阶段, Driver 会将 Task 和 Task 所依赖的 file 和 jar 序列化后传递给对应的 Worker 机器,同时 Executor 对相应数据分区的任务进行处理。

Spark 的整体流程为: Client 提交应用, Master 找到一个 Worker 启动 Driver , Driver 向 Master 或者资源管理器申请资源,之后将应用转化为 RDD Graph ,再由 DAGScheduler 将 RDD Graph 转化为 Stage 的有向无环图提交给 TaskScheduler ,由 TaskScheduler 提交任务给 Executor 执行。在任务执行的过程中,其他组件协同工作,确保整个应用顺利执行。

2 术语解释

RDD :是 Resillient Distributed Dataset (弹性分布式数据集)的简称,是分布式内存的一个抽象概念,提供了一种高度受限的共享内存模型。

DAG :是 Directed Acyclic Graph (有向无环图)的简称,反映 RDD 之间的依赖关系。

Application :用户编写的 Spark 应用程序。

Executor :是运行在工作节点( WorkerNode )的一个进程,负责运行 Task 。

Task :运行在 Executor 上的工作单元 。

Job :一个 Job 包含多个 RDD 及作用于相应 RDD 上的各种操作。

Stage :是 Job 的基本调度单位,一个 Job 会分为多组 Task ,每组 Task 被称为 Stage , 或者也被称为 TaskSet ,代表了一组关联的、 相互之间没有 Shuffle 依赖关系的任务组成的任务集。

3 架构原理介绍

3.1 Spark 依赖

( 1 ) Map Reduce 模型

作为一个分布式计算框架, Spark 采用了 MapReduce 模型。在它身上, Google 的 Map Reduce 和 Hadoop 的痕迹很重,很明显,它并非一个大的创新,而是微创新。在基础理念不变的前提下,它借鉴,模仿并依赖了先辈,加入了一点改进,极大的提升了 MapReduce 的效率。

使用 MapReduce 模型解决大数据并行计算的问题,带来的最大优势,是它和 Hadoop 的同属一家人。因为同属于 MapReduce 并行编程模型,而不是 MPI 和 OpenMP 其它模型,因此,复杂的算法,只要能够以 Java 算法表达,在 Hadoop 上运行的,就能以 Scala 算法表达,在 Spark 上运行,而速度有倍数的提升。相比之下,在 MPI 和 Hadoop 算法之间切换,难度就大多了。

( 2 )函数式编程

Spark 由 Scala 写就,而支持的语言亦是 Scala 。其原因之一就是 Scala 支持函数式编程。这一来造就了 Spark 的代码简洁,二来使得基于 Spark 开发的程序,也特别的简洁。一次完整的 MapReduce , Hadoop 中需要创建一个 Mapper 类和 Reduce 类,而 Spark 只需要创建相应的一个 map 函数和 reduce 函数即可,代码量大大降低。

( 3 ) Mesos
Spark 将分布式运行的需要考虑的事情,都交给了 Mesos ,自己不 Care ,这也是它代码能够精简的原因之一。

( 4 ) HDFS 和 S3
Spark 支持 2 种分布式存储系统: HDFS 和 S3 。应该算是目前最主流的两种了。对文件系统的读取和写入功能是 Spark 自己提供的,借助 Mesos 分布式实现。如果自己想做集群试验,又没有 HDFS 环境,也没有 EC2 环境的话,可以搞个 NFS ,确保所有 MESOS 的 Slave 都可以访问,也可以模拟一下。

3.2 Spark 架构

Spark 架构图如下:





Spark 架构中的基本组件

ClusterManager :在 Standalone 模式中即为 Master (主节点),控制整个集群,监控 Worker 。在 YARN 模式中为资源管理器。

Worker :从节点,负责控制计算节点,启动 Executor 或 Driver 。在 YARN 模式中为 NodeManager ,负责计算节点的控制。

Driver :运行 Application 的 main() 函数并创建 SparkContext 。

Executor :执行器,在 worker node 上执行任务的组件、用于启动线程池运行任务。每个 Application 拥有独立的一组 Executors 。

SparkContext :整个应用的上下文,控制应用的生命周期。

RDD : Spark 的基本计算单元,一组 RDD 可形成执行的有向无环图 RDD Graph 。

DAG Scheduler :根据作业( Job )构建基于 Stage 的 DAG ,并提交 Stage 给 TaskScheduler 。

TaskScheduler :将任务( Task )分发给 Executor 执行。

SparkEnv :线程级别的上下文,存储运行时的重要组件的引用。

SparkEnv 内创建并包含如下一些重要组件的引用。

MapOutPutTracker :负责 Shuffle 元信息的存储。

BroadcastManager :负责广播变量的控制与元信息的存储。

BlockManager :负责存储管理、创建和查找块。

MetricsSystem :监控运行时性能指标信息。

SparkConf :负责存储配置信息。

Spark 结构主要分为四个部分:

1. 用来提交作业的 Client 程序: client 是什么呢,比如 spark 中提交程序的 shell 窗口,宏观上讲,是一台提交程序的物理机。负责将打包好的 spark 程序提交到集群中,提交完程序这个客户端客户端程序还发挥什么作用呢? yarn-client 模式下,客户端提交程序后,在该客户端上又运行着一个 driver 程序,这个 client 的作用持续到 spark 程序运行完毕,而 yarn-cluster 模式下,客户端提交程序后就不再发挥任何作用,也就是说仅仅发挥了提交程序包的作用。

2. 用来驱动程序运行的 Driver 程序: driver 完成的工作主要是创建用户的上下文,这个上下文中包括很多控件比如 DADScheduler 、 TaskScheduler 等等,这些控件完成的工作也称为 driver 完成的。 driver 中完成 RDD 的生成,将 RDD 划分成有向无环图,生成 task ,接受 master 的指示将 task 发送到 worker 节点上进行执行等工作。

3. 用来进行资源调度的 ClusterManager: 整个集群的 master ,主要完成资源的调度,涉及一些调度算法,自带的资源管理器只支持 FIFO 调度, yarn 和 mesos 还支持其他方式的调度算发。 CM 一边和 driver 打交道 ,一边和 worker 打交道, driver 向 CM 申请资源, worker 通过心跳机制向 CM 汇报自己的资源和运行情况, CM 告诉 driver 应该向哪些 worker 发送消息, 然后 driver 把 task 发送到这些可用的 worker 上

4. 用来执行程序的 worker:worker 用多个 executor 来执行程序

3.3 Spark 运行模式