《Spark Streaming实时流式大数据处理实战》 ——3.2 RDD存储结构
3.2 RDD存储结构
RDD实现的数据结构核心是一个五元组,如表3.1所示。
表3.1 RDD实现的数据结构核心
//RDD中的依赖关系由一个Seq数据集来记录,这里使用Seq的原因是经常取第一个元素或者遍历
protected def getDependencies: Seq[Dependency[_]] = deps
// 分区列表定义在一个数组中,这里使用Array的原因是随时使用下标来访问分区内容
// @transient分区列表不需要被序列化
protected def getPartitions: Array[Partition]
// 接口定义,具体由子类实现,对输入的RDD分区进行计算
def compute(split: Partition, context: TaskContext): Iterator[T]
// 分区器
// 可选,子类可以重写以指定新的分区方式,Spark支持Hash和Range两种分区方式 @transient
val partitioner: Option[Partitioner] = None
// 可选,子类可以指定分区的位置,如HadoopRDD可以重写此方法,让分区尽可能与数据在
相同的节点上
protected def getPreferredLocations(split: Partition): Seq[String] = Nil
RDD设计的一个重要优势是能够记录RDD间的依赖关系,即所谓血统(lineage)。我们通过丰富的转移操作(Transformation),可以构建一个复杂的有向无环图,并通过这个图来一步步进行计算。RDD的这5个核心属性(见表3.1)起到了非常关键的作用,并且由Spark设计之初一直保存到现在。
在讲解RDD属性时,我们多次提到了分区(partition)的概念。分区是一个偏物理层的概念,也是RDD并行计算的核心。数据在RDD内部被切分为多个子集合,每个子集合可以被认为是一个分区,我们的运算逻辑最小会被应用在每一个分区上,每个分区是由一个单独的任务(task)来运行的,所以分区数越多,整个应用的并行度也会越高。
- 点赞
- 收藏
- 关注作者
评论(0)