RDD源码分析--Iterator

本文详细介绍了Spark中RDD(弹性分布式数据集)的工作原理及其实现机制,包括如何通过RDD进行数据操作,如map操作的具体流程,以及RDD如何与实际存储的数据集合建立联系。

RDD,Resilient Distributed Datasets,弹性分布式数据集。

在Spark中,通俗地可以认为是一个数据集合,只不过这个数据集合分布在不同的机器上,对外表现为一个整体。

一般来讲,对RDD进行操作比如map操作时分为两步,第一步为局部操作,即是对每台机器上的RDD的部分数据都进行map并行操作,第二步为汇总操作,将每台机器的执行结果进行汇总。

其中有一个问题是,RDD中的数据集合是分布的,RDD是如何确定每台机器上的数据集合的位置的呢?RDD是如何跟实际存储数据的集合对应起来的呢?

查看RDD源码

查看Partition源码

返回值Iterator为Scala自带类,参数split通过查看Partition不难看出是一个RDD的一个分区的标识,也就是说,通过输入参数某个分区的标识就可以获得这个分区的数据集合的迭代器,RDD与实际的某台机器上的数据集合就是这么联系起来的。RDD的Iterator方法只有这么一个,但是这个方法只能用来遍历某个Partition的数据,不能遍历整个RDD中的全部数据。

查看RDD的map方法

查看MapPartitionsRDD

在map方法中,返回值是一个新创建的MapPartitionRDD,不同于RDD是一个抽象类,MapPartitionRDD方法有自己的实现。

MapPartitionRDD类中的compute方法,是调用构造函数中的参数f,f是一个函数,f函数又是从map方法传入的,也就是说,map方法把具体要做的实现的函数传入MapPartitionsRDD,MapPartitionsRDD根据函数的不同有不同的实现,这就是scala的一个好处了,通过传入不同的函数参数可以实现不同的方法。在第三个参数中firstParent[T].iterator(split, context)中,可以看到iterator方法,所以f(context, split.index, firstParent[T].iterator(split, context))最终的返回值是一个Partition数据集合的一个迭代器,通过这个迭代器,RDD的map函数就能与实际的数据集合的map函数联系起来啦。

### RDD 的创建方式(Scala) 在 Apache Spark 中,弹性分布式数据集(Resilient Distributed Dataset, RDD)是其核心抽象之一。RDD 可以通过两种主要方式创建:从外部存储系统中加载数据,或从内存中的集合转换而来。 #### 从集合创建 RDD 使用 `SparkContext.parallelize()` 方法可以将 Scala 集合(如 List、Array 等)转换为分布式 RDD。该方法会将本地集合切分为多个分区,并分发到集群的不同节点上进行处理[^1]。 ```scala val sparkConf = new SparkConf().setAppName("RDDCreation").setMaster("local[*]") val sc = new SparkContext(sparkConf) val data = Array(1, 2, 3, 4, 5) val rdd = sc.parallelize(data) ``` 上述代码中,`parallelize` 将本地数组转化为一个并行化的 RDD,可用于后续的分布式操作。 #### 从外部数据源创建 RDD 另一种常见方式是从文件系统(如本地文件系统、HDFS、S3 等)读取文本文件生成 RDD。Spark 提供了 `textFile` 方法来实现这一功能[^1]。 ```scala val rddFromFile = sc.textFile("path/to/input.txt") ``` 此方法适用于处理大规模文本数据,每一行对应 RDD 中的一个元素。支持多种格式,包括 CSV、JSON(需额外解析)、SequenceFiles 等。 #### 从其他 RDD 转换而来 任何已有的 RDD 都可以通过转换操作(如 `map`、`filter`、`flatMap` 等)生成新的 RDD。这种惰性求值机制使得 Spark 能够优化执行计划[^1]。 ```scala val lines = sc.textFile("input.txt") val words = lines.flatMap(_.split(" ")) ``` 这里 `words` 是由 `lines` 经过 `flatMap` 操作派生出的新 RDD。 #### 使用 `makeRDD` 创建 `SparkContext` 还提供了 `makeRDD` 方法,类似于 `parallelize`,但可指定每个分区所在的首选位置,适用于需要控制数据分布的场景[^1]。 ```scala val rddWithLocs = sc.makeRDD(List(1, 2, 3, 4), 2) ``` 该方法底层仍调用 `parallelize`,但在某些高级用例中提供更灵活的配置选项。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值