Spark Core 解析:RDD

本文深入解析Spark Core中的RDD,包括其定义、特征、分区与Partitioner、算子、函数、Dependency、RDD分类、Checkpoint、Cache、Broadcast及Accumulators等内容,帮助读者全面了解RDD在Spark中的作用和实现原理。
摘要由CSDN通过智能技术生成

引言

Spark Core是Spark的核心部分,是Spark SQL,Spark Streaming,Spark MLlib等等其他模块的基础, Spark Core提供了开发分布式应用的脚手架,使得其他模块或应用的开发者不必关心复杂的分布式计算如何实现,只需使用Spark Core提供的分布式数据结构RDD及丰富的算子API,以类似开发单机应用的方式来进行开发。

spark.png

图中最下面那个就是Spark Core啦,日常使用的RDD相关的API就属于Spark Core,而Dataset、DataFrame则属于Spark SQL。

RDD 概览

RDD是Spark Core的用户级API,了解RDD是了解Spark Core的第一步,本文基于Spark 2.x,主要对RDD的特点和组成进行分析。

定义

RDD (Resilient Distributed Dataset,弹性分布式数据集):

  • Resilient:不可变的、容错的
  • Distributed:数据分散在不同节点(机器,进程)
  • Dataset:一个由多个分区组成的数据集

特征

In-Memory:RDD会优先使用内存Immutable(Read-Only):一旦创建不可修改Lazy evaluated:惰性执行Cacheable:可缓存,可复用Parallel:可并行处理Typed:强类型,单一类型数据Partitioned:分区的Location-Stickiness:可指定分区优先使用的节点

是Spark中最核心的数据抽象,数据处理和计算基本都是基于RDD。

组成

一个RDD通常由5个要素组成:

  • 一组分区(partition)
  • 一个计算函数
  • 一组依赖(直接依赖的父RDD)
  • 一个分区器 (可选)
  • 一组优先计算位置(e.g. 将Task分配至靠近HDFS块的节点进行计算) (可选)

与传统数据结构对比,只关心访问,不关心存储。通过迭代器访问数据,只要数据能被不重复地访问即可。后面会详细分析各要素。

算子

算子,即对RDD进行变换的操作,按照是否触发Job提交可以分为两大类:

  • transformation:不会立即执行的一类变换,不会触发Job执行,会生成并返回新的RDD,同时记录下依赖关系。如:map,filter,union,join,reduceByKey。
  • action: 会立即提交Job的一类变换,不会返回新的RDD,而是直接返回计算结果。如:count,reduce,foreach。

20191022162739.png

下面对RDD的组成要素进行分析

Partition & Partitioner

为什么要把数据分区?把数据分成若干partition是为了将数据分散到不同节点不同线程,从而能进行分布式的多线程的并行计算。

按什么规则分区?RDD从数据源生成的时候,数据通常是随机分配到不同的partition或者保持数据源的分区,如sc.parallelize(…),sc.textFile(…)。

这对于某些RDD操作来说是没有问题的,比如filter(),map(),flatMap(),rdd.union(otherRDD),rdd.intersection(otherRDD),rdd.subtract(otherRDD)。

但是对于reduceByKey(),foldByKey(),combineByKey(),groupByKey(),sortByKey(),cogroup(), join() ,leftOuterJoin(), rightOuterJoin()这些操作,随机分配分区就非常不友好,会带来很多额外的网络传输。影响一个分布式计算系统性能的最大敌人就是网络传输,所以必须尽量最小化网络传输。

为了减少网络传输,怎么分区才合理?对于reduceByKey操作应该把相同key的数据放到同一分区;对于sortByKey操作应该把同一范围的数据放到同一分区。

可见不同的操作适合不同的数据分区规则,Spark将划分规则抽象为Partitioner(分区器) ,分区器的核心作用是决定数据应归属的分区,本质就是计算数据对应的分区ID。

在Spark Core中内置了2个Partitioner来支持常用的分区规则(Spark MLlib,Spark SQL中有其他的)。

  • HashPartitioner 哈希分区器
  • RangePartitioner 范围分区器

HashPartitioner

哈希分区器是默认的分区器,也是使用最广泛的一个,作用是将数据按照key的hash值进行分区。

分区ID计算公式非常简单:key的hash值 % 分区个数 , 如果key为null,则返回0.

也就是将key的hash值(Java中每个对象都有hash code,对象相等则hash code相同),除以分区个数,取余数为分区ID,这样能够保证相同Key的数据被分到同一个分区,但是每个分区的数据量可能会相差很大,出现数据倾斜。

RangePartitioner

RangePartitioner的作用是根据key,将数据按范围大致平均的分到各个分区

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值