Spark 学习笔记
Spark 概述
本文为在学习厦门大学 MOOC 课程《大数据技术原理与应用》时所记重点笔记,顺序按照课程顺序
Spark 与 Scala
Spark 为一门用 Scala 开发的大数据框架,成名类似于 Hadoop,Spark 在 2014 年刷新了 Hadoop 之前保持的 1TB 数据基准排序的记录,到现在成为了一个基于内存计算的大数据并行计算框架,可用于构建大型的、低延迟的数据分析应用。
Spark 特点
- 运行速度快:使用 DAG 执行引擎来进行作业调度,效率要比 MapReduce 高效的多
- 容易使用:支持多种编程方式
- 通用性:Spark 提供了完整而强大的技术栈
- 内存计算 Spark Core
- 包括 SQL 查询分析 Spark SQL
- 流式计算 Spark Streaming
- 机器学习 Spark MLib
- 图算法 GraphX
- 运行模式多样
Scala 语言是一门现代的多范式编程语言(比如函数式、面向对象、过程式),平滑的集成了面向对象和函数式编程两种风格可以运行于 Java 平台(JVM)之上。
Scala 特性
- 强大的并发性,支持函数式编程,支持分布式系统
- 语法简洁,提供优雅 API
- Scala 兼容 Java,且能融入到 Hadoop 生态圈
- 提供 REPL(交互式解释器),提高开发效率
Spark 与 Hadoop 的对比
Hadoop 的缺点
- 表达能力有限:不是所有应用都能用 Map 和 Reduce 表达
- 磁盘 IO 开销较大
- 延迟高
- 任务之间衔接涉及到 IO 开销
- 前一个任务完成前其他任务无法开始。难以胜任复杂、多阶段的任务计算
Spark 相比 Hadoop MapReduce 的优点
- 计算模式属于 MapReduce 但提供多种数据集操作类型是编程模型更灵活
- Spark 提供内存计算,迭代计算不需要读写磁盘
- Spark 基于 DAG 任务调度机制
Spark 生态系统
在实际应用中,大数据处理包括三个类型:
- 复杂的批量处理,数十分钟到几小时。MapReduce
- 基于历史数据的交互式查询,数十秒到数分钟。Cloudera Impala
- 基于实时数据流处理,毫秒到数秒之间。Storm
由此带来的问题:
- 不同场景输入输出数据无法做到无缝共享
- 不同软件需要不同的开发和维护,较高的使用成本
- 比较难对同一个集群中的各个系统进行统一的资源协调分配
Spark 设计遵循“一个软件栈满足不同应用场景”的理念,逐渐形成了一整套生态系统 Spark 可以部署在 YARN 之上,提供一站式的数据解决方案 Spark 所提供的生态系统足以应对上述三种场景 Spark 生态系统已成为 BDAS(伯克利大学数据实验室软件栈) 的重要组成
Spark 运行架构
基本概念
- 弹性分布式数据集(RDD,Resillient Distributed Dataset)是分布式内存的抽象概念,提供了一种高度受限的共享内存模型
- 有向无环图(DAG)反映了 RDD 之间的依赖关系
- Executor,是运行在工作节点的一个进程,负责运行 Task
- Application,用户编写的 Spark 应用程序
- Task,运行在 Executor 之上的工作单元
- Job,一般一个 Application 包含多个 Job,一个 Job 包含多个 RDD 及作用于相应 RDD 上的各种操作
- Stage,是 Job 调用的基本单位,一个 Job 会分为多组 Task,每组 Task 被称为 Stage,或者称为 TaskSet,代表了一组关联的、相互之间没有 Shuffle 依赖关系的任务组成的任务集
Spark 基本架构设计
- Cluster Manager,集群资源管理器,负责对整个 Spark 应用程序来进行集群资源管理分配和调度。可以自带或 Mesos 或 YARN
- Work Node,运行作业任务的工作节点
- Driver Program,每个应用的任务控制节点,生成 DAG,对 DAG 进行分成多个阶段,对阶段进行拆解,吧任务分给相关具体的 Executor 执行都是由 Driver 执行
- Executor,负责每个工作节点上具体任务执行的进程
该架构设计与 Hadoop MapReduce 相比优点
- 利用多线程来执行具体的任务减少任务的启动开销
- Executor 中有一个 BlockManager,会将内存和磁盘共同视为存储设备,有效减少 IO 开销
Spark 中各种概念之间的相互关系
Spark 运行基本流程
- 为应用构建起基本的运行环境,即由 Driver 创建一个 SparkContext 进行资源的申请、任务的分配和监控
- 资源管理器为 Executor 分配资源,并启动 Executor 进程,进程会汇报资源的使用情况
- SparkContext 根据 RDD 的依赖关系构建 DAG 图,DAG 图提交给 DAG Scheduler 解析成 Stage,然后吧一个个 TaskSet 提交给底层调度器 Task Scheduler 处理;Executor 主动向 SparkContext 申请 Task,Task Scheduler 将 Task 发放给 Executor 运行并提供应用程序代码
- Task 在 Executor 上运行把执行结果反馈给 TaskScheduler,然后反馈给 DAGScheduler,运行完毕后写入数据并释放所有资源
Spark 运行架构特点
- 每个 AppIication 都有自己专属的 Executor 进程,并且该进程在 AppIication 运行期间一直驻留。Executor 进程以多线程的方式运行 Task
- Spark 运行过程与资源管理器无关,只要能够获取 Executor 进程并保持通信即可
- Task 采用了数据本地性和推测执行等优化机制
RDD
RDD 基本概念
设计背景:许多迭代式算法(比如机器学习)和交互式数据挖掘工具,共同之处是,不同计算阶段之间会重用中间结果,目前 MapReduce 框架都是吧中间结果写入到磁盘中带来非常大的磁盘 IO 开销和序列化的开销。RDD 就是为了满足这种需求而出现,它提供了一个抽象的数据结构,将应用逻辑表达式进行一些列的转换。不同的 RDD 之间的转换操作形成以依赖关系(DAG 图),可以实现管道化,一个 RDD 的结果可以作为下一个 RDD 的输入,避免中间数据存储
RDD 概念:一个 RDD 就是一个分布式对象集合,本质上是一个只读的分区记录集合,毎个 RDO 可分成多个分区,毎个分区就是一个数据集片段,并且一个 RDD 的不同分区可以被保存到集群中不同的节点上,从而可以在集群中的不同节点上进行并行计算。 RDD 提供了一种高度受限的内存共享模型,即 RDD 是只读的记录分区的集合,不能直接修改,只能基于稳定的物理存储中的数据集创建 RDD,或者通过在其他 RDD 上执行确定的转换操作(如 map、join、group by)而创建得到新的 RDD
RDD 提供了两种操作来支持常见的数据运算:
- 转换(Transformation):转换接口非常简单,类似 map、filter 这种粗粒度的数据转换,而不能对某个数据项进行修改(不适合网页爬虫)
- 动作(Action)
RDD 典型执行过程
- RDD 读入外部数据源进行创建数据,根据数据大小创建不同分区,不同分区放到不同数据节点上
- RDD 经过一系列转换操作,每一次都会产生不同的 RDD 供给下一个转换使用,不计算结果,只记录轨迹
- 最后一个 RDD 经过动作操作计算产生结果
- 这一系列处理成为一个 Lineage(血缘关系)反映了不同 RDD 之间的依赖关系,即 DAG 拓扑排序的结果
RDD 特性
- 高效的容错性。容错机制:血缘关系的设计方式使得 RDD 天生具有容错性,当一个 RDD 分区出现错误,只需要往上层节点追溯并再次转换即可
- 中间结果持久化到内存:数据在内存中的多个 RDD 操作之间进行传递,降低磁盘开销
- 存放的数据可以是 Java 对象,避免了不必要的对象序列化和反序列化
RDD 的依赖关系和运行过程
Spark 通过分析各个 RDD 的依赖关系生成了 DAG 图再通过分析各个 RDD 中的分区之间的依赖关系(宽依赖、窄依赖)来决定如何划分 Stage
- 窄依赖:表现为一个父 RDD 的分区对应于一个子 RDD 的分区或者多个父 RDD 的分区对应于一个子 RDD 的分区
- 宽依赖:一个父 RDD 的一个分区对应于一个子 RDD 的多个分区
具体划分方法
- 在 DAG 中进行反向解析,遇到宽依赖就断开(存在 Shuffle)
- 遇到窄依赖酒把当前的 RDD 加入 Stage
- 将窄依赖尽量划分在同一个 Stage 中,可以实现流水线计算从而使得数据可以直接在内存中进行交换
如图可以看出,RDD A 和 B 之间是宽依赖,所以 A 被单独划分为一个 Stage 1,CDFE 之间都是窄依赖,可以直接划分成一个 Stage 2 构成流水化作业,之后 B 到 G 是窄依赖,F 到 G 为宽依赖,所以最后根据划分方法总共划分为三个 Stage
Stage 的类型
- ShuffleMapStage:不是最终的 Stage,在他之后还有其他的 Stage,所以它的输出一定要经过 Shuffle 过程,并作为后续 Stage 的输入。这种 Stage 是以 Shuffle 为输出边界(存在宽依赖断开),其输入边界可以是从外部获取数据,也可以使另一个 ShuffleMapStage 的输出其输出可以使另一个 Stage 的开始
- ResultStage:没有输出,而是直接产生结果或存储。zhezhongStage 是直接输出结果,其输入边界可以是从外部获取数据也可以是另一个 ShuffleMapStage 的输出。一个 Job 必定会有至少一个 ResultStage
Spark SQL
SparkSQL 在 Hive 兼容层面仅依赖 HiveQL 解析、Hive 元数据也就是说,从 HQL 被解析成抽象语法树(AST) 起,就全部由 SparkSQL 接管了。SparkSQL 执行计划生成和优化都由 Catalyst(函数式关系查询优化框架)负责
SparkSQL 增加了 SchemaRDD(即带有 Schema 信息的 RDD) 使用户可以在 SparkSQL 中执行 SQL 语句
备注:SchemaRDD 在后来的 SparkSQL 版本中演化为 DataFrame
Spark 部署和应用
Spark 三种部署方式
- Standalone:自带的资源管理框架。类似 MapReduce1.0,slot 为资源分配单位,但是不进行 map slot 和 reduce slot 切分
- Spark on Mesos:Spark 和 Mesos 相互支持比较充分
- Spark on YARN
不同计算框架统一运行在 YARN 中的优势:
- 计算资源按需伸缩
- 不用付在应用混搭、集群利用率高
- 共享底层存储,避免数据库跨集群迁移
Spark 编程实践