Spark 基础
# 一、Spark 概述
# 1.1 Spark 是什么
Spark 是一种基于内存的快速、通用、可扩展的大数据分析计算引擎。
Spark 是加州大学伯克利分校 AMP 实验室(Algorithms Machines and People Lab)开发的通用大数据出来框架。Spark 生态栈也称为 BDAS,是伯克利 AMP 实验室所开发的,力图在算法(Algorithms)、机器(Machines)和人(Person)三种之间通过大规模集成来展现大数据应用的一个开源平台。AMP 实验室运用大数据、云计算等各种资源以及各种灵活的技术方案,对海量数据进行分析并转化为有用的信息,让人们更好地了解世界。2010 年开源, 2013 年 6 月成为 Apache 孵化项目,2014 年 2 月成为 Apache 顶级项目,用 Scala 进行编写项目框架。
# 1.2 Spark 特点
- 速度快
由于 Apache Spark 支持内存计算,并且通过 DAG(有向无环图)执行引擎支持无环数据流,所以官方宣称其在内存中的运算速度要比 Hadoop 的 MapReduce 快 100 倍,在硬盘中要快 10 倍。
Spark 相对 MapReduce 更快的原因:
- 减小磁盘 IO。Spark 允许将计算的中间结果存储到内存里,而不是像 MapReduce 一样写到磁盘上。
- 增加并行度。Spark 中的任务是以线程的方式执行的,且由于 Spark 将不同的环节抽象成 Stage,允许多个 Stage 并行执行。
- 避免重复计算。基于 Spark 中的 DAG 可以避免重复计算。
- 易于使用
Spark 支持 Java、Python 和 Scala 的 API,还支持超过 80 种高级算法,使用户可以快速构建不同的应用。而且 Spark 支持交互式的 Python 和 Scala 的 Shell,可以非常方便地在这些 Shell 中使用 Spark 集群来验证解决问题的方法。
- 通用性强
在 Spark 的基础上,Spark 还提供了包括 Spark SQL、Spark Streaming、MLib 及 GraphX 在内的多个工具库,我们可以在一个应用中无缝地使用这些工具库。其中,Spark SQL 提供了结构化的数据处理方式,Spark Streaming 主要针对流式处理任务(也是本书的重点),MLlib 提供了很多有用的机器学习算法库,GraphX 提供图形和图形并行化计算。
- 兼容性强
Spark 可以非常方便地与其他的开源产品进行融合。比如,Spark 可以使用 Hadoop 的 YARN 和 Apache Mesos 作为它的资源管理和调度器,并且可以处理所有 Hadoop 支持的数据,包括 HDFS、HBase 等。这对于已经部署 Hadoop 集群的用户特别重要,因为不需要做任何数据迁移就可以使用 Spark 的强大处理能力。
# 1.3 Spark 组件
Spark 框架模块包含 Spark Coke、 Spark SQL、 Spark Streaming、 Spark GraphX、Spark MLlib,而后四项的能力都是建立在核心引擎之上。新版中还扩展出了新的流计算组件 Structured Streaming。
- Spark Core
实现了 Spark 的基本功能,包含任务调度、内存管理、错误恢复、与存储系统交互等模块。Spark Core 中还包含了对弹性分布式数据集(Resilient Distributed DataSet,简称 RDD)的 API 定义。
- Spark SQL
是 Spark 用来操作结构化数据的程序包。通过 Spark SQL,我们可以使用 SQL 或者 Apache Hive 版本的 SQL 方言(HQL)来查询数据。Spark SQL 支持多种数据源,比如 Hive 表、Parquet 以及 JSON 等。
- Spark Streaming
是 Spark 提供的对实时数据进行流式计算的组件。提供了用来操作数据流的 API,并且与 Spark Core 中的 RDD API 高度对应。
- Spark MLlib
提供常见的机器学习(ML)功能的程序库。包括分类、回归、聚类、协同过滤等,还提供了模型评估、数据导入等额外的支持功能。
- Spark GraphX
Spark 中用于图计算的 API,性能良好,拥有丰富的功能和运算符,能在海量数据上自如地运行复杂的图算法。
- Structured Streaming
Structured Streaming 是结构化流处理模块,将流式结构化数据封装到 DataFrame 中进行分析。是建立在 SparkSQL 引擎之上的可伸缩和高容错的流式处理引擎,可以像操作静态数据的批量计算一样来执行流式计算。当流式数据不断的到达的过程中 Spark SQL 的引擎会连续不断的执行计算并更新最终结果。简而言之,Structured Streaming 提供了快速、可伸缩、可容错、端到端精确的流处理。
# 二、Spark 运行模式
# 2.1 运行模式
Spark 的运行模式主要可以分为三类:Local 模式、集群模式和云服务模式。其中集群模式可以分 Standalone、Yarn 和 Mesos 三种,云服务模式主要是 Kubernetes 模式。
- Local 模式
Local 模式也就是本地模式,将 Spark 应用程序中任务 Task 运行在一个本地 JVM Process 进程中,通常开发测试使用。
- Standalone 模式
搭建采用 Master + Worker 模式的集群,使用 Spark 内置的任务调度模块进行任务调度和资源管理。
- Yarn 模式
搭建采用 Master + Worker 模式的集群,借助 Yarn 进行任务调度和资源管理,Spark 只负责计算,生产环境用的最多。
- Mesos
运行在 Mesos 资源管理器框架之上,由 Mesos 负责资源管理,Spark 负责任务调度和计算。国内很少使用。
- Kubernetes
Spark 2.3 开始支持将 Spark 开发应用运行到 Kubernetes 上。
# 2.2 部署模式
Spark Application 的部署模式分为 Client 和 Cluster 两种。两种模式的主要区别是 Driver 程序运行在哪个主机上,默认是 Client 模式,但是在工作中都采用 Cluster 模式,通过--deploy-mode cluster
参数指定。
# 2.2.1 Client 模式
表示应用 Driver 运行在提交应用的 Client 主机上(启动 JVM Process 进程),示意图如下:
# 2.2.2 Cluster 模式
应用 Driver 运行在集群从节点 Worker 某台机器上,示意图如下:
# 三、Spark 术语
# 3.1 集群相关
- Cluster Manager:Spark 的集群管理者,主要负责对整个集群资源的管理与分配。Standalone 模式下为 Master,Yarn 模式下为 ResourceManager;
- Worker:Spark 的工作节点。在 Yarn 模式下由 NodeManager 替代。主要负责:
- 将自己的内存、CPU 等资源信息向 Cluster Manager 注册
- 创建 Executor
- 将资源和任务分配给 Executor
- 同步资源信息、Executor 状态信息
# 3.2 任务相关
- Driver:Spark Application 驱动程序。它负责创建 SparkContext、创建 RDD,以及进行 RDD 的转化操作和行动操作代码的执行。如果你是用 Spark Shell,那么当你启动 Spark Shell 的时候,系统后台自启了一个 Spark 驱动器程序,就是在 Spark Shell 中预加载的一个叫作 sc 的 SparkContext 对象。如果驱动器程序终止,那么 Spark 应用也就结束了。主要负责:
- 把用户程序转为 Job;
- 跟踪 Executor 的运行状况
- 为执行器节点调度任务
- UI 展示应用运行状况
- Executor:是运行在工作节点 Worker 上的进程,负责在 Spark 作业中运行任务,任务间相互独立。Spark 应用启动时,Executor 节点被同时启动,并且始终伴随着整个 Spark 应用的生命周期而存在。如果有 Executor 节点发生了故障或崩溃,Spark 应用也可以继续执行,会将出错节点上的任务调度到其他 Executor 上继续运行。主要负责:
- 运行组成 Spark 应用的任务,并将结果返回给驱动器进程;
- 通过自身的块管理器(Block Manager)为用户程序中要求缓存的 RDD 提供内存式存储。
- Application:指的是用户编写的 Spark 应用程序/代码,包含了 Driver 功能代码和分布在集群中多个节点上运行的 Executor 代码。初始化一个 SparkContext 即生成一个 Application;
- DAG:Directed Acyclic Graph 有向无环图,反映 RDD 之间的依赖关系和执行流程;
- Job:一个 Action 算子就会生成一个 Job;
- Stage:阶段,是作业的基本调度单位,遇到一个宽依赖则划分一个 Stage。同一个 Stage 中的 Task 可以并行执行,多个 Task 组成 TaskSet 任务集;
- Task:任务,运行在 Executor 上的工作单元,1 个 Task 计算 1 个分区,包括 pipline 上的一系列操作;
- Partition:数据分区,一个 RDD 可以划分为多个分区,Spark 根据 Partition 数量来确定 Task 的数量,一个 Partition 对应一个 Task。
提示
Application -> Job -> Stage -> Task 每一层都是 1 对 n 的关系。
一个 main 方法就会产生一个或多个 Application,一个 Application 里面可以有多个 action 算子,每个 action 算子会产生一个 Job,所以一个 Application 可以有多个 Job; 一个 Job 可以有多个 Stage;一个 Stage 可以多个 Task。