Spark基础
核心特性
1) 内存计算
Apache Spark在内存中存储中间数据的能力使其处理数据的速度比传统的基于磁盘的系统快得多。
2) 统一分析
Apache Spark提供了一个用于批处理、实时流、机器学习和交互式查询的单一平台,减少了对多种工具的需求。
3) 支持多种语言
Spark支持包括Java、Scala、Python和R等多种编程语言,使其可供广大开发人员使用。
分布式大数据计算
- 数据拆分
- 移动计算逻辑比移动计算数据更划算
Spark代码是如何运行的

Spark 应用程序通常由以下几个主要组件组成:
-
Driver Program:主控制器,负责协调和管理 Spark 应用程序的执行。它包含应用程序的主逻辑。
-
Cluster Manager:集群管理器,负责资源管理和调度。常见的有 Standalone、YARN、Mesos 等。
-
Workers:工作节点,实际运行任务的节点,每个 Worker 运行多个 Executor。
Spark Driver
Apache Spark Driver是声明SparkContext的程序,SparkContext负责将用户程序转换为可以在集群中分布的一系列任务。它还协调任务的执行,并与集群管理器通信,为应用程序分配资源。简而言之,Spark驱动程序在管理Spark应用程序的整体执行中起着至关重要的作用。
Spark 代码通常使用 Scala、Java、Python 或 R 编写。下面是一个简单的 PySpark 示例:
from pyspark import SparkContext
sc = SparkContext("local", "Simple App")
data = [1, 2, 3, 4, 5]
rdd = sc.parallelize(data)
result = rdd.map(lambda x: x * x).collect()
print(result)
Spark Executor
Spark中Executor是一个进程,负责在集群中的工作节点上并行运行任务。Spark驱动程序启动Executor进程,并在工作节点上运行以执行驱动程序分配的任务。因此,了解Spark Driver和Executor之间的区别至关重要。
Executor是Spark运行时架构的关键组件,因为它负责在工作节点上并行处理数据和执行代码。Executor运行用户定义的Spark代码,可以用Scala、Java、Python或R等多种编程语言编写,并使用RDD(弹性分布式数据集)API或DataFrame API对数据进行必要的计算和转换。
Spark Executor Configurations
--executor-memory: 指定每个执行器分配的内存量(例如,1GB为1g)
--num-executors: 指定要启动的执行器数量
--executor-cores: 指定为每个执行器分配的核心数量
--conf spark.executor.extraClassPath: 为执行器指定额外的类路径条目
--conf spark.executor.extraJavaOptions: 为执行器指定额外的Java选项
--conf spark.executor.extraLibraryPath: 为执行器指定额外的库路径条目
--conf spark.yarn.executor.memoryOverhead: 指定每个执行器要分配的非堆内存量
--conf spark.executor.memoryFraction: 指定为spark内存管理分配的堆空间分数
--conf spark.dynamicAllocation.enabled: 启用或禁用执行器的动态分配
代码提交
https://spark.apache.org/docs/latest/submitting-applications.html
3.1 提交方式
用户通过命令行、IDE 或者 Spark 提供的 Web 界面提交 Spark 应用程序。提交时,用户需要指定主类、集群模式、资源需求等参数。
spark-submit
--driver-memory: 指定分给driver的内存大小,例如1g
--driver-cores: 指定要为驱动程序分配的核心数量
--driver-class-path: 指定驱动程序的类路径
--driver-java-options: 指定为驱动程序指定额外的java选项
--driver-library-path: 指定驱动程序的库路径
--conf spark.driver.maxResultSize: 限制spark返回给驱动程序的结果的最大大小
--conf spark.driver.host: 指定驱动程序运行的主机名或IP地址
| 参数名称 | 参数说明 | 运行模式 |
|---|---|---|
| --master | master 的地址,提交任务到哪里执行,支持5种: spark://host:port, mesos://host:port, yarn, k8s://https://host:port local (Default: local[*]) | all |
| --deploy-mode | 在本地 (client) 启动 driver 或在 cluster 上启动,默认是 client | all |
| --class | 应用程序的主类,仅针对 java 或 scala 应用 | |
| --name | 应用程序名称 | all |
| --jars | 用逗号分隔的本地 jar 包,设置后,这些 jar 将包含在 driver 和 executor 的 classpath 下 | all |
| --packages | 包含在driver 和executor 的 classpath 中的 jar 的 maven 坐标 | all |
| --exclude-packages | 为了避免冲突 而指定不包含的 package | all |
| --repositories | 远程 repository | all |
| --file | 用逗号分隔的文件,这些文件被放在每个executor的工作目录,并通过SparkFiles.get(fileName)访问 | all |
| --conf PROP=VALUE | 指定 spark 配置属性的值, 例如 -conf spark.executor.extraJavaOptions="-XX:MaxPermSize=256m" | all |
| --properties-file | 加载的配置文件,默认为 conf/spark-defaults.conf | all |
| --driver-memory | Driver内存,默认 1024M | all |
| --driver-java-options | 传给 driver 的额外的 Java 选项 | all |
| --driver-library-path | 传给 driver 的额外的库路径 | all |
| --driver-class-path | 传给 driver 的额外的类路径 | all |
| --executor-memory | 每个 executor 的内存,默认是1G | all |
| --driver-cores | driver使用的cpu核数,默认为1 | yarn/standalone |
| --total-executor-cores | 所有 executor 总共的核数。 | mesos/standalone |
| --executor-core | 每个 executor 的核数。 | yarn/standalone |
| --num-executors | 启动的 executor 数量。默认为2 | yarn |
| --queue | 提交应用程序给哪个YARN的队列,默认是default队列 | yarn |
| --archives | 被每个executor提取到工作目录的档案列表,用逗号隔开 | yarn |
代码打包
Spark 会将用户的代码和依赖库打包成 JAR 文件(对于 Scala/Java)或将 Python 脚本(对于 PySpark)打包。
- 代码运行流程
4.1 Driver 启动
Driver 程序启动:用户提交代码后,Cluster Manager 启动 Driver 程序。
初始化 SparkContext:Driver 中创建 SparkContext,初始化 Spark 应用程序的环境和配置。
4.2 任务划分
RDD 创建:用户通过操作(如 parallelize、textFile 等)创建 RDD(弹性分布式数据集)。
转换操作:调用转换操作(如 map、filter 等)时,Spark 会构建一个逻辑执行计划(DAG),但不会立即执行。
4.3 依赖分析
Spark 会分析 RDD 之间的依赖关系,构建一个有向无环图(DAG),每个节点代表 RDD,每条边代表操作。
4.4 任务提交给 Cluster Manager
Task 划分:Spark 将整个计算过程划分为多个小任务,每个任务处理 RDD 的一个分区。
资源请求:Driver 向 Cluster Manager 请求资源,提交任务。
4.5 Worker 执行任务
Worker 启动 Executor:Cluster Manager 将任务分配给 Worker,Worker 启动 Executor 来执行任务。
数据处理:Executor 执行任务,处理数据并将计算结果存储在内存或磁盘中。
4.6 结果返回
任务完成:每个 Executor 完成任务后,将结果返回给 Driver。
收集结果:Driver 收集所有任务的结果,可能会进一步处理或输出最终结果。
5. 任务调度与容错
调度:Spark 使用 DAG 调度器来管理任务执行,确保任务按依赖顺序执行。
容错机制:如果某个任务失败,Spark 会根据 RDD 的血统信息(lineage)重新计算丢失的数据,而不是重新执行整个应用程序。
6. 结果输出
Spark 可以将结果输出到多种数据存储系统中,如 HDFS、S3、数据库等。
基础架构
集群模式
https://spark.apache.org/docs/latest/cluster-overview.html
Spark应用程序在集群上作为独立的一组进程运行,由驱动程序中的SparkContext对象进行协调。我们写的带有main方法的Sprak程序就是驱动程序。要在集群上运行,SparkContext可以连接到多种类型的集群管理器(可以是Spark自带的Standalone集群管理器、YARN或Kubernetes),这些管理器会在应用程序之间分配资源。一旦连接成功,Spark就会在集群中的节点上获取执行器,这些Executor就是操作系统进程,用于应用程序运行计算和存储数据。

关于这种架构,有几点需要注意:
- 每个应用程序都有自己的执行器进程,这些进程在整个应用程序的运行期间一直保持运行,并在多个线程中执行任务。这样做的好处是,无论是在调度方面(每个驱动程序调度自己的任务)还是在执行器方面(来自不同应用程序的任务在不同的JVM中运行),都能实现应用程序之间的隔离。然而,这也意味着,如果不将数据写入外部存储系统,就无法在不同的Spark应用程序(SparkContext的实例)之间共享数据。
- Spark对底层集群管理器持中立态度。只要它能获取执行器进程,并且这些进程之间能够相互通信,那么即使在同时支持其他应用程序(如YARN/Kubernetes)的集群管理器上运行它也相对容易。
- 驱动程序在其整个生命周期中必须监听并接受来自其执行器的传入连接。因此,驱动程序必须能够从工作节点通过网络寻址
- 因为驱动程序在集群上调度任务,所以它应该在工作节点附近运行,最好在同一局域网上运行。如果你想远程向集群发送请求,最好向驱动程序打开一个RPC,让它从附近提交操作,而不是在远离工作节点的地方运行驱动程序。
Executor、Task、Stage、Job
一个action对应一个job,一个job多个stage,划分stage的边界是不同节点取数据,到shuffle结束,一个stage对应多个task,task由dirver发送到executor,task运行在executor中,exector运行在worker node上,exector由dirver在worker node上申请资源创建,application包括driver program和executors。
|
Application
|
基于Spark的用户程序。由集群上的Driver program和Executor组成。
|
|
Application jar
|
一个包含用户的Spark应用程序的jar。在某些情况下,用户将希望创建一个包含其应用程序及其依赖项的“uber jar”。
用户的jar不包含Hadoop或Spark库,但是这些库将在运行时添加。
|
|
Driver program
|
该进程运行应用程序的main()函数并创建SparkContext
|
|
Cluster manager
|
用于获取集群上资源的外部服务(例如,standalone manager, Mesos, YARN)
|
|
Deploy mode
|
区分驱动程序进程的运行位置。在“
cluster”模式下,框架在集群内部启动驱动程序。在“
client”模式下,用户在集群外部启动
driver。
|
|
Worker node
|
可以在集群中运行应用程序代码的任何节点
|
|
Executor
|
Worker node上的应用程序启动的进程,该进程运行任务并将数据跨任务存储在内存或磁盘存储中。每个应用程序都有自己的执行程序。
|
|
Task
|
发送给某个Executor的工作单元
|
|
Job
|
一种由多个任务组成的并行计算,这些任务对应一些Spark操作(例如
`save`,
`collect`
);可以在Driver
日志中看到job。
|
|
Stage
|
每个
job 都被分为一些较小的任务集,这些任务集就是
_stages_(类似于MapReduce中的map和reduce阶段),stage是相互依赖的;
可以在Driver
日志中看到Stage
。
|
任务调度
https://spark.apache.org/docs/latest/job-scheduling.html
参考资料:

浙公网安备 33010602011771号