一、窄依赖(narrow dependency)
窄依赖是指:每一个父RDD
的一个partition
最多被子RDD
的一个partition
所使用,例如:map,filter,union
等操作会产生窄依赖,相当于父母和独生子女的关系
二、宽依赖(shuffle denpendency)
宽依赖是指:每一个父RDD
的一个partition
多个子RDD
的一个partition
所使用,每一个父RDD
的一个partition
有可能传输部份数据到子RDD
的每一个partition中,子RDD
的多个partition
依赖于父RDD
例如:groupByKey,reduceByKey,sortedByKey
,二者关系相当于父母超生了。
三、Spark
- 基本概念:RDD、DAG、Executor、Application、Task、Job、Stage
- RDD:弹性分布式数据集,是分布式内存的一个抽象概念,提供一个高度共享的内存模型。
- DAG:有向无环图,用来表示Spark流程中,各个RDD之间的血缘关系,即RDD之间的依赖。
- Executor:运行在工作节点上的一个进程,负责运行任务,并为应用程序存储数据。
- Application:用户编写的Spark应用程序。
- Task:运行在Executor上的工作单元。
- Job:一个作业包含多个RDD以及作用于相应RDD上的各种操作。
- Stage:是作业的基本调度单元,一个作业会分为多组任务,每组任务被称为”Stage“,也称任务集。
四、Spark的架构设计
Spark的运行架构包括集群资源管理器(Cluster Manager
)、工作节点(Worker Node
)、任务控制节点(Driver
)、执行进程(Executor
)。其中集群资源管理器可以是Spark自带的资源管理器,也可以是Yarn
等资源管理框架。
在Spark
中,一个Application
由一个任务控制节点Driver
和多个作业Job
构成,一个作业由多个Stage
构成,一个Stage
由多个Task
组成。当执行一个Application
时,控制节点会向集群管理器Cluster Manager
申请资源,启动Executor
,并向Executor
发送应用程序代码和文件,然后在Executor
执行任务,运行结束以后,执行结果会返回给任务控制节点,或者写到HDFS
或者其他数据库。
五、Spark的运行流程
- 当一个Spark应用被提交时,首先要为这个应用构建一个基本的运行环境,即由任务控制节点
Driver
创建一个SparkContext
,由SparkContext
和集群资源管理器Cluster Manager
通信和进行资源的申请、任务的分配与监控等。SparkContext
会向资源管理器注册并申请运行Executor
的资源。 - 资源管理器为
Executor
分配资源,并启动Executor
进程,Executor
运行情况随着心跳发送给资源管理器。 SparkContext
根据RDD的依赖关系构建DAG
图,DAG
图提交给**DAG
调度器DAGScheduler
进行解析,将DAG
图分解为多个Stage
,每个阶段都是一个任务集,并计算出各阶段之间的依赖关系,然后将一个个任务集提交给底层的任务调度器TaskScheduler
进行处理;Executor
向SparkContext
申请任务,任务调度器将任务分配给Executor
运行,同时,SparkContext
将应用程序代码发送给Executor
**。- 任务在
Executor
上运行,把执行结果反馈给任务调度器,然后反馈给DAG调度器,运行完以后写入数据并释放所有资源。
六、Spark运行架构的特点
- 每个应用程序都有自己的专属
Executor
进程,并且该进程会在任务运行期间一直存在,Executor
进程以多线程的方式运行任务,减少多进程任务频繁的开启开销,使任务执行变得高效和可靠。 - Spark运行过程与资源管理器无关,只要能获取
EXecutor
进程并保持通信即可。 - Executor上有一个BlockManager存储模块,类似于键值存储系统(把内存和磁盘共同作为存储设备),在处理迭代计算任务时,不需要把中间结果写入到HDFS等文件系统,而是直接放在这个存储系统上,后续有需要时就可以直接读取;在交互式查询场景下,也可以把表提前缓存到这个存储系统上,提高读写IO性能。
- 任务采用了数据本地性和推测执行等优化机制。数据本地性是尽量将计算移到数据所在的节点上进行,即“计算向数据靠拢”,因为移动计算比移动数据所占的网络资源要少得多。而且,Spark采用了延时调度机制,可以在更大的程度上实现执行过程优化。比如,拥有数据的节点当前正被其他的任务占用,那么,在这种情况下是否需要将数据移动到其他的空闲节点呢?答案是不一定。因为,如果经过预测发现当前节点结束当前任务的时间要比移动数据的时间还要少,那么,调度就会等待,直到当前节点可用。
待处理:Executor
进程以多线程的方式运行任务,查一下详细信息