千家信息网

如何理解Spark中的核心概念RDD

发表于:2026-11-03 作者:千家信息网编辑
千家信息网最后更新 2026年11月03日,如何理解Spark中的核心概念RDD,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。RDD全称叫做弹性分布式数据集(Resilient D
千家信息网最后更新 2026年11月03日如何理解Spark中的核心概念RDD

如何理解Spark中的核心概念RDD,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。

RDD全称叫做弹性分布式数据集(Resilient Distributed Datasets),它是一种分布式的内存抽象,表示一个只读的记录分区的集合,它只能通过其他RDD转换而创建,为此,RDD支持丰富的转换操作 ( 如: map, join, filter, groupBy 等),通过这种转换操作,新的RDD则包含了如何从其他RDDs衍生所必需的信息,所以说RDDs之间是有依赖关系的。

基于RDDs之间的依赖,RDDs会形成一个有向无环图DAG,该DAG描述了整个流式计算的流程,实际执行的时候,RDD是通过血缘关系(Lineage)一气呵成的,即使出现数据分区丢失,也可以通过血缘关系重建分区。

总结起来,基于RDD的流式计算任务可描述为:从稳定的物理存储(如分布式文件系统)中加载记录,记录被传入由一组确定性操作构成的DAG,然后写回稳定存储。另外RDD还可以将数据集缓存到内存中,使得在多个操作之间可以重用数据集,基于这个特点可以很方便地构建迭代型应用(图计算、机器学习等)或者交互式数据分析应用。

可以说Spark最初也就是实现RDD的一个分布式系统,后面通过不断发展壮大成为现在较为完善的大数据生态系统,简单来讲,Spark-RDD的关系类似于Hadoop-MapReduce关系。

RDD特点

RDD表示只读的分区的数据集,对RDD进行改动,只能通过RDD的转换操作,由一个RDD得到一个新的RDD,新的RDD包含了从其他RDD衍生所必需的信息。

RDDs之间存在依赖,RDD的执行是按照血缘关系延时计算的。如果血缘关系较长,可以通过持久化RDD来切断血缘关系。

分区

如下图所示,RDD逻辑上是分区的,每个分区的数据是抽象存在的,计算的时候会通过一个compute函数得到每个分区的数据。

如果RDD是通过已有的文件系统构建,则compute函数是读取指定文件系统中的数据,如果RDD是通过其他RDD转换而来,则compute函数是执行转换逻辑将其他RDD的数据进行转换。

只读

如下图所示,RDD是只读的,要想改变RDD中的数据,只能在现有的RDD基础上创建新的RDD。

由一个RDD转换到另一个RDD,可以通过丰富的操作算子实现,不再像MapReduce那样只能写map和reduce了,如下图所示。

RDD的操作算子包括两类,一类叫做transformations,它是用来将RDD进行转化,构建RDD的血缘关系;另一类叫做actions,它是用来触发RDD的计算,得到RDD的相关计算结果或者将RDD保存的文件系统中。下图是RDD所支持的操作算子列表。

依赖

RDDs通过操作算子进行转换,转换得到的新RDD包含了从其他RDDs衍生所必需的信息,RDDs之间维护着这种血缘关系,也称之为依赖。如下图所示,依赖包括两种,一种是窄依赖,RDDs之间分区是一一对应的,另一种是宽依赖,下游RDD的每个分区与上游RDD(也称之为父RDD)的每个分区都有关,是多对多的关系。

通过RDDs之间的这种依赖关系,一个任务流可以描述为DAG(有向无环图),如下图所示,在实际执行过程中宽依赖对应于Shuffle(图中的reduceByKey和join),窄依赖中的所有转换操作可以通过类似于管道的方式一气呵成执行(图中map和union可以一起执行)。

缓存

如果在应用程序中多次使用同一个RDD,可以将该RDD缓存起来,该RDD只有在***次计算的时候会根据血缘关系得到分区的数据,在后续其他地方用到该RDD的时候,会直接从缓存处取而不用再根据血缘关系计算,这样就加速后期的重用。

如下图所示,RDD-1经过一系列的转换后得到RDD-n并保存到hdfs,RDD-1在这一过程中会有个中间结果,如果将其缓存到内存,那么在随后的RDD-1转换到RDD-m这一过程中,就不会计算其之前的RDD-0了。

Checkpoint

虽然RDD的血缘关系天然地可以实现容错,当RDD的某个分区数据失败或丢失,可以通过血缘关系重建。但是对于长时间迭代型应用来说,随着迭代的进行,RDDs之间的血缘关系会越来越长,一旦在后续迭代过程中出错,则需要通过非常长的血缘关系去重建,势必影响性能。

为此,RDD支持checkpoint将数据保存到持久化的存储中,这样就可以切断之前的血缘关系,因为checkpoint后的RDD不需要知道它的父RDDs了,它可以从checkpoint处拿到数据。

小结

总结起来,给定一个RDD我们至少可以知道如下几点信息:1、分区数以及分区方式;2、由父RDDs衍生而来的相关依赖信息;3、计算每个分区的数据,计算步骤为:1)如果被缓存,则从缓存中取的分区的数据;2)如果被Checkpoint,则从Checkpoint处恢复数据;3)根据血缘关系计算分区的数据。

编程模型

在Spark中,RDD被表示为对象,通过对象上的方法调用来对RDD进行转换。经过一系列的Transformations后,就可以调用Actions触发RDD的计算,Action可以是向应用程序返回结果( count, collect 等),或者是向存储系统保存数据( saveAsTextFile 等)。在Spark中,只有遇到Action,才会执行RDD的计算(即懒执行),这样在运行时可以通过管道的方式传输多个转换。

要使用Spark,开发者需要编写一个Driver程序,它被提交到集群以调度运行Worker,如下图所示。Driver中定义了一个或多个RDD,并调用RDD上的action,Worker则执行RDD分区计算任务。

应用举例

下面介绍一个简单的Spark应用程序实例WordCount,统计一个数据集中每个单词出现的次数,首先将从HDFS中加载数据得到原始RDD-0,其中每条记录为数据中的一行句子,经过一个flatMap操作,将一行句子切分为多个独立的词,得到RDD-1,再通过map操作将每个词映射为key-value形式,其中key为词本身,value为初始计数值1,得到RDD-2,将RDD-2中的所有记录归并,统计每个词的计数,得到RDD-3,***将其保存到HDFS。

object WordCount { def main(args: Array[String]) { if (args.length < 2) { System.err.println("Usage: WordCount  "); System.exit(1); } val conf = new SparkConf().setAppName("WordCount") val sc = new SparkContext(conf) val result = sc.textFile(args(0)) .flatMap(line => line.split(" ")) .map(word => (word, 1)) .reduceByKey(_ + _)  result.saveAsTextFile(args(1)) } }

结语

基于RDD实现的Spark相比于传统的Hadoop MapReduce有什么优势呢?总结起来应该至少有三点:

1.RDD提供了丰富的操作算子,不再是只有map和reduce两个操作了,对于描述应用程序来说更加方便;

2.通过RDDs之间的转换构建DAG,中间结果不用落地;

3.RDD支持缓存,可以在内存中快速完成计算。

看完上述内容,你们掌握如何理解Spark中的核心概念RDD的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注行业资讯频道,感谢各位的阅读!

数据 血缘 之间 缓存 应用 系统 可以通过 信息 程序 算子 内存 分布式 多个 应用程序 文件 时候 结果 过程 存储 支持 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 百单网互联网科技有限公司 中关村互联网 科技集团 重生之互联网科技帝国 互联网是不是新科技 互联网科技战争 科技类互联网 广州互联网科技公司 上海互联网科技有限公司 世界互联网领先科技成果 左右互联网络科技 中国互联网有什么科技含量 互联网科技寓意 金融科技与互联网金融相同和不同 河南猎农互联网科技有限公司 浙南科技城互联网大厦建设工程 内蒙古九一互联网科技 互联网数据科技专业 宁波跨境商互联网科技有限公司 广东鹅鹅鹅互联网科技有限公司 10位科技互联网大佬 深圳市人人互联网科技有限公司 上海挚品互联网科技 贷财互联网科技 掌上梦互联网科技 团飞科技与伯堂互联网服务平台 厦门千工互联网科技有限公司 坤平互联网科技 乌苏新华互联网科技做什么的 每天都有哪些好的互联网科技 玉溪新华互联网科技怎么选
0