(六)Spark源码理解之RDD

本文深入探讨了Spark中的RDD概念,解释了其组成部分,包括依赖关系、分区列表及计算函数,并详细说明了persist和unpersist方法的作用,以及如何在实际场景中应用RDD。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

       RDD看起来好像很抽象,但我的理解就是类似于我们自己写一个java程序,会编写一个数据模型的类来组织我们的数据一样,RDD其实就是Spark中的数据模型,也就是Spark自己编写的类,RDD有三个必不可少的部分:(1)RDD对其他RDD的依赖,即血系图;(2)分区列表;(3)针对分区的计算函数;

(1)RDD对其他RDD的依赖

1.1 RDD中persist和unpersist方法实质上就是往SparkContext类中定义的TimeStampedWeakValueHashMap[Int, RDD[_]]变量中添加或者删除RDD记录(包括RDD的id,RDD本身);

1.2 Dependency

Dependency体现出RDD的依赖关系,通过它可以获得血系图,Dependency中一个最重要的方法就是getParent()

def getParents(partitionId: Int): Seq[Int]//输入子RDD的一个分区id,返回子RDD的该分区所依赖的父RDD的分区id所组成的序列

为什么getParents没有方法的实现呢?

我是这样理解的:如一对一依赖,子RDD和父RDD是一对一的,而且子RDD沿用父RDD的分区id,那子RDD调用该方法是实质返回的也就是自己的分区id,因此直接可以用Seq[Int]了,至于宽依赖好像就不好理解了,不过思路就是宽依赖中子RDD要依赖父RDD的所有分区

(2)分区列表

2.1 Partitioner

划分器,宽依赖即shuffle操作时用到,用来对shuffle的输出结果进行分区(包括分区id,分区的位置等),窄依赖或者说一对一依赖时不需要,因为子RDD会沿用父RDD的分区信息(包括分区的位置,分区id等),默认的分区器为HashPartitioner哈希划分器,分区数目一般默认为“spark.default.parallelism”指定的值(通常为2)

<script src="https://code.youkuaiyun.com/snippets/624739.js"></script>

此外划分器还有RangePartitioner范围划分器,当然我觉得自己也可以实现自己的划分器,只需要在Partitioner类中实现一个自定义的划分器类,然后在Partitioner类中的defaultPartitioner方法中将new HashPartitioner改为自己定义的类就好了,不过这需要对spark重新进行编译,划分器的效率关系的shuffle操作的性能

2.2. Partition

Partition类即分区类,该类中重写了hashCode()方法,返回的是分区索引;

RDD中调用partitions()方法返回RDD中各个分区索引数组,即Array[Partition]

未完待续。。。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值