五分钟了解Spark之RDD!!
Spark之探究RDD
如何了解一个组件,先看看官方介绍!
进入RDD.scala,引入眼帘的是这么一段描述文字(渣翻勿喷):
RDD,弹性分布式数据集,是Spark中的基础抽象。代表了一个可以被并行化操作的不可变、可分区的要素集合。这个类包含了任何RDD都可使用的基本操作,例如map,filter。
此外,PairRDDFuncations声明了只有KV对 RDD才可使用的操作,例如groupByKey、join;DoubleRDDFuncations声明了只有Doubles RDD才可使用的操作;SequenceFileRDDFuncations声明了只有可序列化RDD才可使用的操作。所有的操作都是通过隐式调用对于右侧任何RDD自动可用的。例如 RDD[(Int, Int)]。
在内部,每一个RDD都有以下五个主要的属性:
- 一个分区列表
- 作用到每个分区的计算函数
- 依赖RDD列表
- 【可选】对于KV类型的RDD会有一个Partitioner(例如,定义某个RDD是Hash分区的)
- 【可选】每个分区的首选计算执行任务
在Spark中,所有任务调度和执行都是基于这些方法,并且允许RDD覆盖这些方法以实现自己的计算;更进一步说,用户可以覆盖这些方法实现自己的逻辑(例如,从一个新的存储系统读数据)。请参考《Spark paper》以了解更多关于RDD内部的信息。
源码中的介绍就到这里结束了,让我们来看看之中的关键点。
RDD弹性分布式数据集
重要结论:RDD是一个数据集,记录了这个数据集从哪里来,怎么计算
数据从哪里来?
源头RDD的数据从数据源来,RDD2的数据从源头RDD来,以此类推。
数据怎么计算?
计算就是操作,在上文RDD源码中,说到RDD包含了许多基本的操作,例如map。那不难理解,所谓计算就是调用这些操作,而这些操作可以分成两类:
- Transformation转换操作:返回一个新的RDD
- Action动作操作:返回值不是RDD(无返回值或返回其他)
一般来说,会根据RDD调用的是哪类操作,从而定义为转换算子或执行算子。
那如果转换操作是将一个RDD转化为另一个RDD,那不是也可以理解为某种“Action”吗?所以,转换操作不是真正的转换,而是“将一个RDD重新嵌套成了另一个RDD”,而“重新嵌套”实质上就是把自己的计算逻辑套在了前一个RDD上面。
而,Action操作,就是真正的“动作”了。
当最后一个RDD触发Action操作后,大概是这么调用的:
(RDDn的计算逻辑(...(RDD2的计算逻辑(RDD1的计算逻辑)))).Action
所以当Action后,一直深入到RDD1开始计算,再逐级返回。从图中理解,大概是某种“拉式”调用。
那如果没有最后的Action,结果会怎样呢?很明显,无事发生!
数据存在哪里?
从上面的过程,可以理解到,RDD不实际存储真正要计算的数据,而是记录了数据的位置在哪里,数据的转换关系。RDD这一条链就像是一本操作手册,只记录了对数据的操作,而实际执行这些操作的并不是它。
数据到哪里去?
欸,这个不归RDD管哈哈,RDD并不会操心数据到哪里去。
最后
以上就是RDD最简单的理解了,其实还有很多需要深入的地方,以及如何关联Spark其他组件;例如,如果说RDD是一本电饭煲使用说明,那使用人是谁呢?(Driver),电饭煲又是哪个东西呢?(集群),饭在哪里呢?(数据源)。至此,感谢阅读!