Spark基本架构
从集群部署的角度来看,Spark集群由集群管理器(Cluster Manager)、工作节点(Worker)、执行器(Executor)、驱动器(Driver)、应用程序(Application)等部分组成。
Cluster Manager
Spark的集群管理器,主要负责对整个集群资源的分配与管理。Cluster Manager分配的资源属于一级分配,它将各个Worker上的内存、CPU等资源分配给Application,但是并不负责对Executor的资源分配。Worker
Spark的工作节点。Worker节点主要负责以下工作,将自己的内存,CPU等资源通过注册机制告知Cluster Manager;创建Executor;将资源和任务进一步分配给Executor;同步资源信息、Executor状态信息给Cluster Manager等。Executor
执行计算任务的一线组件。主要负责任务的执行及与Worker、Driver的信息同步。Driver
Application的驱动程序,Application通过Driver与Cluster Manager、Executor进行通信。Driver可以运行在Application中,也可以由Application提交给Cluster Manager并由Cluster Manager安排Worker运行Application
用户编写的应用程序,Application通过Spark提供的API进行RDD的转换和DAG构建,并通过Driver将Application注册到Cluster Manager。Cluster Manager将会根据Application的资源需求,通过一级分配将Executor、内存、CPU等资源分配给Application。Driver通过二级分配将Executor等资源分配给每一个任务,Application最后通过Driver告诉Executor运行任务。
什么是RDD?
Resilient Distributed Datasets,弹性分布式数据集。是分布式内存的一种抽象概念,是一种高度受限的共享内存模型,即RDD是只读的记录分区的集合,能横跨集群的所有节点进行并行计算,是一种基于工作集的应用抽象。
RDD底层存储:
RDD的数据分布存储于多台机器上(HDFS Block形式)
RDD中的Partition是一个逻辑数据结构,存储数据分区以及逻辑结构的映射关系,存储着RDD之前的依赖转换关系。
RDD的5个主要的属性
- 一组分片(Partition):数据集的基本组成单位。对于RDD来说,每个分片都会被一个计算任务(Task)处理,分区的数量决定了并行计算的粒度。RDD的并行度默认从父RDD传给子RDD。默认情况下,一个HDFS上的数据分片(Block)就是一个partition,HDFS文件的Block数决定了该RDD的分区数。也可以在创建RDD的时候指定RDD的分片个数,如果不指定分区数量,当RDD从集合创建时,默认分区数量为该程序多分配到资源的CPU核数(每个Core可以承载2-4个partition)。
- 一个作用于每个分区的函数:RDD中的计算是以分片为单位的,每个RDD都会实现compute函数,RDD的分片是并行计算的。
- RDD之间的依赖关系:RDD的每次转换都会生成一个新的RDD,所以RDD之间就会形成类似于流水线一样的前后以来关系。在部分分区数据丢失时,Spark可以通过这个以来关系重新计算丢失的分区数据,而不是对RDD的所有分区进行重新计算。
- 一个Partitioner:RDD的分片函数。只有对于Key-value类型的RDD,才会有Partitioner。Partitioner函数不但决定了RDD本身的分片数量,也决定了parent RDD shuffle输出时的分片数量。
- 一个存储每个Partition的优先位置列表(preferred location):对于一个HDFS文件来说,这个列表保存的就是每个Partition所在的快的位置。Spark在进行任务调度的时候,会尽可能地将计算任务分配到其索要处理数据块的存储位置(移动数据不如移动计算)。
Spark应用程序的执行过程?
- 构建Spark Application的运行环境(启动SparkContext),SparkContext向资源管理器(Standalone,YARN或Mesos)注册并申请运行Executor资源
- 资源管理器分配Executor资源并启动StandaloneExecutorBackend,Executor运行情况将随着心跳发送到资源管理器上
- SparkContext构建DAG图,将DAG图分解成STage,并把Taskset发送给TaskScheduler。Executor向SparkContext申请Task,TaskScheduler将Task发送给Executor运行,同时SparkContext将应用成怒代码发送给Executor
- Task在Executor上运行,运行完毕释放所有资源
Spark中cache和persist的区别?
cache和persist都是用于将一个RDD进行缓存的,这样在之后使用的过程中就不需要重新计算了,可以大大节省程序运行时间。
cache只有一个默认的缓存级别MEMORY_ONLY
,cache调用了persist,而persist可以根据情况设置其他的缓存级别。