【Spark系列2】Spark编程模型RDD

RDD概述

RDD最初的概述来源于一片论文-伯克利实验室的Resilient Distributed Datasets:A Fault-Tolerant Abstraction for In-Memory Cluster Computing。这篇论文奠定了RDD基本功能的思想

RDD实际为Resilient Distribution Datasets的简称,意为弹性分布式数据集

RDD的基本属性

1、分区

RDD的中文含义是弹性分布式数据集,其中分区的概念实现了分布式所需的功能。每个分区中包含一部分数据,通过对每个分区的数据计算以及最后对结果数据的汇总,从而实现对整个数据集的计算。RDD的计算是以分区为单位进行的,而且同一分区的所有数据都进行相同的计算。对于同一分区的数据而言,要么全执行,要么全不执行。理论上分区越多,能够并行计算任务数据越多,但还是会收到物理资源如CPU等的限制。

2、计算函数

RDD的数据被分区了,但是每个分区的数据是如何来的呢,一个RDD的数据来源只有两种:一是从数据源或集合中进行加载运行的到RDD的数据;而是通过其他RDD进行一定的转换的来的数据,无论哪种方式,RDD的数据都是通过其计算函数得到的。计算函数compute返回值为迭代器器类型。

如Spark在加载HDFS中的数据时,每个分区的数据通过计算函数加载对应的block块的数据,从而实现了数据分布式加载的过程,如下图

Spark还可以从集合中创建RDD,实现每个分区加载集合中的一部分数据,如SparkContext中实现的parallelize的并行集合的方法。甚至可以自定义分区函数实现特定加载数据的方式,如将历史数据按照时间分区进行加载

3、依赖

在RDD进行转换过程中,子RDD是通过父RDD转换而来的。但在具体的实现过程中,所有RDD的数据都是通过其计算函数而得到的,所以,子RDD在计算过程中需要得到父RDD的,分局父RDD的数据算出子RDD每个分区的数据。

在RDD计算时有些子RDD的一个分区只依赖父RDD的一个分区,即每个父RDD的分区最多被子RDD的一个分区所使用,则这种依赖方式称为窄依赖,如下图

在RDD计算时,如果一个分区的数据依赖了父RDD多个分区的数据,即多个子RDD的分区数据依赖了父RDD的同一个分区的数据,这种依赖方式称为宽依赖

4、分区器

并不是所有的RDD都有分区器(partitioner),一般只有(Key,Value)形式的RDD才有分区器。分区器在Shuffle的Map阶段使用,当RDD的计算发生Shuffle时,Map阶段虽然将结果进行保存,供Reduce阶段的任务来拉取数据,但是Map阶段的每个分区的数据可能会被Reduce阶段的多个分区使用。如何把Map阶段的数据进行分组,区分出时给Reduce阶段的RDD哪个分区使用呢,这就是分区器(pattitioner)的作用

5、首选运行位置

每个RDD对于每个分区来说都有一组首选运行位置,用于表示RDD的这个分区数据最好能在哪台主机上运行。通过RDD的首选运行位置,可以让RDD的某个分区的计算任务直接在指定主机上运行,从而实现了移动计算而不是移动数据的目的,减小了网络传输的开销,如Spark中HadoopRDD能够实现加载数据的任务在相应的数据节点上执行

RDD的缓存

如果一个RDD在计算完成后,不是通过流水线的方式被一个RDD调用,而是被多个RDD调用,则在计算过程中就需要对RDD进行缓存,避免二次计算。尤其是一个RDD经过多次特别复杂的Shuffle生成的数据,缓存之后可以极大的提升程序运行的效率。

因为RDD是分布式的,不同的分区散落在不同的物理节点上,所以RDD的缓存也是分布式的。让对RDD进行缓存时,可以将每个分区的数据直接缓存在当前计算节点,每个计算节点缓存一部分数据,完成整个RDD的缓存,如图

RDD的容错机制

RDD的容错时通过lineage机制实现的。因为每个RDD的数据都可以通过其父RDD转换而来。如果运行的过程中,某一个分区的数据丢失,则重新计算该分区的数据。当此RDD的依赖时窄依赖时,只需要计算依赖的父RDD的一个分区的数据即可,避免了一个节点出错则所有数据节点都重新计算的缺点。但是如果丢失数据的RDD的依赖是宽依赖,那么分区的数据可能是父依赖的所有分区数据,这种情况下必须重新计算父RDD分区的所有数据,从而完成数据的恢复

Spark RDD的操作

Spark定义了很多对RDD的操作,主要分为两类:transformation 和 action。transformation操作并不会真正的触发Job的执行,它只是定义了RDD和RDD之间的lineage,只有action操作才会触发Job的真正执行。

1、transformation操作

在Spark中,主要的transformation操作如下

操作 说明
map 迭代RDD中的每个元素生成新的RDD
filter 对RDD的元素进行过滤
flatMap 和Map类似,将每个元素转为0个或多个元素
mapPartitions 迭代每个分区,这在操作数据库时,可以将每个分区创建一个连接
distinct 将数据去重,涉及shuffle
groupByKey 按照Key进行分组
reduceByKey 按照Key进行聚合
union 将两个RDD整合成一个RDD
coalesce 减小分区数量,一般用在执行filter,过滤掉大量数据后调用
repartition 重新分区,这会在城所有的数据进行shuffle

2、action操作

操作 说明
collect 将所有的数据作为一个数据返回Driver程序。当每个分区数据较多,返回Driver中时,可能会造成内存溢出。
count 返回RDD数据的总数
first 返回RDD中的第一个元素
take 将RDD中的前n个元素作为数组返回
saveAsTextFile 将数据写入文件系统
foreach 对RDD中的每个元素都应用给定的函数
reduce 按照给定的函数将数据聚合
相关推荐
廋到被风吹走1 小时前
【Spring】Spring Cloud 分布式事务:Seata AT/TCC/Saga 模式选型指南
分布式·spring·spring cloud
zandy10112 小时前
从 Workflow 到 Agent 模式!衡石多智能体协同架构,重新定义智能 BI 底层逻辑
大数据·信息可视化·架构
Elastic 中国社区官方博客2 小时前
Elastic:DevRel 通讯 — 2026 年 1 月
大数据·数据库·人工智能·elasticsearch·搜索引擎·ai·全文检索
萤丰信息2 小时前
从 “钢筋水泥” 到 “数字神经元”:北京 AI 原点社区重构城市进化新逻辑
java·大数据·人工智能·安全·重构·智慧城市·智慧园区
驾数者3 小时前
Flink SQL容错机制:Checkpoint与Savepoint实战解析
大数据·sql·flink
千汇数据的老司机3 小时前
靠资源拿项目VS靠技术拿项目,二者的深刻区分。
大数据·人工智能·谈单
Elastic 中国社区官方博客5 小时前
jina-embeddings-v3 现已在 Elastic Inference Service 上可用
大数据·人工智能·elasticsearch·搜索引擎·ai·jina
Elastic 中国社区官方博客5 小时前
使用 jina-embeddings-v3 和 Elasticsearch 进行多语言搜索
大数据·数据库·人工智能·elasticsearch·搜索引擎·全文检索·jina
AIFQuant5 小时前
2026 越南证券交易所(VN30, HOSE)API 接口指南
大数据·后端·python·金融·restful
刘一说5 小时前
Spring Cloud微服务中的分布式追踪:从故障定位到性能优化的革命性实践
分布式·spring cloud·微服务