前言
本期将介绍 Spark 中一个抽象的概念——RDD,要学习 Spark 就必须对 RDD 有一个清晰的认知,RDD是 Spark 中最基本的数据抽象,代表一个不可变、可分区、元素可并行计算的集合。
本期学习目标
- RDD 的概念
- RDD 的特点
- RDD 的核心结构
RDD的概念
RRD全称叫做弹性分布式数据集(Resilient Distributed Dataset),从它的名字中可以拆解出三个概念。
- Resilient :弹性的,包括存储和计算两个方面。RDD 中的数据可以保存在内存中,也可以保存在磁盘中。RDD 具有自动容错的特点,可以根据血缘重建丢失或者计算失败的数据;
- Distributed :RDD 的元素是分布式存储的,并且用于分布式计算;
- Dataset : 本质上还是一个存放元素的数据集。
RDD的特点
RDD 具有自动容错、位置感知性调度以及可伸缩等特点,并且允许用户在执行多个查询时,显式地将数据集缓存在内存中,后续查询能够重用该数据集,这极大地提升了查询效率。
下面是源码中对RDD类介绍的注释:
Internally, each RDD is characterized by five main properties:
- A list of partitions
- A function for computing each split
- A list of dependencies on other RDDs
- Optionally, a Partitioner for key-value RDDs (e.g. to say that the RDD is hash-partitioned)
- Optionally, a list of preferred locations to compute each split on (e.g. block locations for an HDFS file)
- 一组分区(Partition)的列表,其中分区也就是RDD的基本组成单位;
- 一个函数会被作用到每个分区上,RDD 的计算是以分区为单位的;
- 一个 RDD 会依赖其他多个 RDD,它们之间具有依赖关系;
- 可选,对于K-V型的RDD会有一个分区函数,控制key分到哪个reduce;
- 一个存储每个分区优先位置的列表。
从源码对 RDD 的定义中,可以看出 RDD 不仅能表示存有多个元素的数据集,而且还能通过依赖关系推算出这个数据集是从哪来的,在哪里计算更合适。
RDD的核心结构
在学习 RDD 转换操作算子之前,根据 RDD 的特点对 RDD 中的核心结构进行一下梳理,这样对 Spark 的执行原理会有一个更深的理解。
-
分区(Partition)
RDD 内部的数据集在逻辑上和物理上都被划分为了多个分区(Partition),每一个分区中的数据都可以在单独的任务中被执行,这样分区数量就决定了计算的并行度。如果在计算中没有指定 RDD 中的分区数,那么 Spark 默认的分区数就是为 Applicaton 运行分配到的 CPU 核数。 -
分区函数(Partitioner)
分区函数不但决定了 RDD 本身的分区数量,也决定了其父 RDD (即上一个衍生它的RDD)Shuffle 输出时的分区数量。Spark 实现了基于 HashPartitioner 的和基于 RangePartitoner 的两种分区函数。
需要特别说明的是,只有对 K-V 类型的 RDD 才会有分区函数。 -
依赖关系
RDD 表示只读的分区的数据集,如果对 RDD 中的数据进行改动,就只能通过转化操作,由一个或多个 RDD 计算得到一个新的 RDD,并且这些 RDD 之间存在着前后依赖关系,前面的称为父 RDD,后面的称为子 RDD。RDD 之间的依赖可分为宽依赖和窄依赖。
当计算过程中出现异常情况导致部分分区数据丢失时,Spark 可以通过这种依赖关系从父 RDD 中重新计算丢失的分区数据,而不需要对 RDD 中的所有分区全部重新计算。 -
Stage
当 Spark 执行作业时,会根据 RDD 之间的依赖关系,按照宽窄依赖生成一个最优的执行计划。如果 RDD 之间为窄依赖,则会被划到一个 Stage 中;如果 RDD 之间为宽依赖,则会被划分到不同的 Stage 中,这样做的原因就是每个 Stage 内的 RDD 都尽可能在各个节点上并行地被执行,以提高运行效率。
-
优先列表(PreferredLocation)
用于存储每个分区优先位置的列表,对于每个 HDFS 文件来说,就是保存下每个分区所在 block 的位置。按照“移动数据不如移动计算”的理念,Spark 在执行任务调度时会优先选择有存储数据的 Worker 节点进行任务运算。 -
CheckPoint
CheckPoint 是 Spark 提供的一种基于快照的缓存机制,如果在任务运算中,多次使用同一个 RDD,可以将这个 RDD 进行缓存处理。这样,该 RDD 只有在第一次计算时会根据依赖关系得到分区数据,在后续使用到该 RDD 时,直接从缓存处取而不是重新进行计算。如下图,对 RDD-1 做快照缓存处理,那么当RDD-n 在用到 RDD-1 数据时,无需重新计算 RDD-1,而是直接从缓存处取数重算。
此外,Spark 还提供了另一种缓存机制 Cache,其中的数据是由 Executor 管理的,当 Executor 消失时,Cache 缓存的数据也将会消失。而 CheckPoint 是将数据保存到磁盘或者 HDFS 中的,当任务运行错误时,Job 会从 CheckPoint 缓存位置取数继续计算。
以上是本期分享,如有帮助请 点赞+关注+收藏 支持下哦~
下期继续讲解 RDD 内容。
前期回顾:
1 - Spark 概述(入门必看)
2 - Spark 的模块组成
3 - Spark 的运行原理