Spark学习笔记之<RDD原理>

在RDD的内部实现中每个RDD都可以使用5个方面的特性来表示:
  1. 分区列表(数据块列表)
  2. 计算每个分片的函数(根据父RDD计算出此RDD)
  3. 对父RDD的依赖列表
  4. 对key-value RDD的Partitioner【可选】
  5. 每个数据分片的预定义地址列表(如HDFS上的数据块的地址)【可选】

物理上,RDD对象实质上是一个元数据结构,存储着Block、Node等的映射关系,以及其他的元数据信息。一个RDD就是一组分区,在物理数据存储上,RDD的每个分区对应的就是一个Block,Block可以存储在内存或者当内存不够时可以存储到磁盘上。


每个Block中存储着RDD所有数据项的一个子集,暴露给用户的可以是一个Block的迭代器。

如果是从HDFS等外部存储作为输入数据源,数据按照HDFS中的数据分布策略进行数据分区,HDFS中的一个Block(128MB或256MB,用户设定的)对应Spark的一个分区(也是一个Block)。同时Spark支持重分区,数据通过Spark默认的或者用户自定义的分区器决定数据库分布在那些节点。


它的容错机制不是通过重新执行map操作或者其他操作来完成的,它主要是通过lineage来恢复数据。注意它是计算框架,和MapReduce一样,而HDFS是存储框架,它也有容错机制,HDFS容错机制是副本机制,即保证固定数量的副本来容错。


RDD的引入提高了抽象层次,在接口和实现上进行有效地隔离,使用户无需关心底层的实现。但是RDD提供给我们的仅仅是一个“”, 我们所操作的数据究竟放在哪里,如何存取?它的“”是怎么样的?这是由storage模块来实现和管理的,接下来我们就要剖析一下storage模块。



Action算子通过SparkContext执行提交作业的runJob操作,触发了RDD DAG的执行。



Spark应用是用户提交的应用程序。执行模式有Local、Standalone、YARN、Mesos。根据Spark Application的Driver Program是否在集群中运行,Spark应用的运行方式又可以分为Cluster模式和Client模式。

应用的基本组件:

Application:用户自定义的Spark程序,用户提交后,Spark为APP分配资源,将程序转换并执行。

Driver Program:运行App的main()函数并创建SparkContext,SparkContext是程序的起点。Driver Program非常重要。应用最终转换成Task的过程都在Driver Program中。

RDD Graph:当RDD遇到Action算子时,将之前的所有算子形成一个有向无环图(DAG),也就是RDD Graph。再在Spark中转化为Job提交到集群中运行。

Job:一个RDD Graph触发的作业,往往有Spark Action算子触发,在SparkContext中通过runJob方法向Spark提交Job

Stage:每个Job会根据RDD的宽依赖关系被切分为很多Stage,每个Stage中包含一组相同的Task,这一组Task为TaskSet

Task:一个分区对应一个Task,Task执行RDD中对应Stage中包含的算子(有多个算子流水线操作)。Task被封装好后放入Executor的线程池中执行。


应用提交与执行方式有两种:①Driver进程运行在客户端,即提交程序的计算机,对应用进行管理监控。②主节点指定某个Worker节点启动Driver,负责整个应用的监控。(主节点是Master,也就是ClusterManager)

Driver进程时应用的主控进程,负责应用的解析、切分Stage并调度Task到Executor执行,包含DAGScheduler、TaskScheduler等。非常重要!


系统设计的一个核心就是调度。从Spark整体上看,调度分为4个级别,Application调度、Job调度、Stage的调度、Task的调度与分发。


Spark作业调度中Stage的划分

Spark在接收到提交的作业后,会进行RDD依赖分析并划分为多个Stage,以Stage为单位生成taskset并提交调度。对RDD的操作分为transformation和action两类,真正的作业提交运行发生在action只够,调用action之后会将对原始输入数据的所有transformation操作封装成作业并向集群提交运行。这个过程大致可以如下描述:

由DAGScheduler对RDD之间的依赖性进行分析,通过DAG来分析各个RDD之间的转换依赖关系。②根据DAGScheduler分析得到的RDD依赖关系将Job划分成多个Stage。③每个Stage会生成一个TaskSet并提交给TaskScheduler,调度权转交给TaskScheduler,由它来负责分发task到worker中Executor执行


Spark中RDD的粗粒度操作,每一次transformation都会生成一个新的RDD,这样就会建立RDD之间的前后依赖关系,在Spark中,依赖关系被定义为两种类型,分别是窄依赖和宽依赖。窄依赖,一个父RDD的一个分区最多只会被一个子RDD的一个分区使用。宽依赖,一个父RDD的一个分区会被一个子RDD的多个分区使用。


stage的划分是Spark作业调度的关键一步,它基于DAG确定依赖关系,借此来划分stage,将依赖链断开,每个stage内部可以并行运行(划分关键点),整个作业按照stage顺序依次执行,最终完成整个Job。

each stage contains as many pipelined transformations with narrow dependencies as possible.


尽管RDD的Lineage可以用来还原数据,但这通常会非常耗时。所以将某些RDD持久化到磁盘上会非常有用,例如前面提到过的,宽依赖的中间数据。对于Spark来说,对检查点的支持非常简单,因为RDD都是不可变的。所以完全可以在后台持久化RDD,而无需暂停整个系统。





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值