Spark的设计与运用原理

Posted 深夜的猫213

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spark的设计与运用原理相关的知识,希望对你有一定的参考价值。

Spark的设计与运用原理

一、概述

Spark最初由美国加州大学伯克利分校的AMP实验室于2009年开发,是基于内存计算的大数据并行计算的大数据并行计算框架,可用于构建大型的、低延迟的数据分析应用程序。

Spark具有如下几个主要特点:

(1)运行速度快:Spark使用先进的有向无环图(DAG)执行引擎,以支持循环数据流与内存计算,基于内存的执行速度可比Hadoop MapReduce快上百倍,基于磁盘的执行速度也要快十倍。

(2)容易使用:Spark支持使用Scala、Java、Python、R语言进行编程。简介的API设计有助于用户轻松构建并行程序,并且可以通过Spark Shell进行交互式编程。

(3)通用性:Spark提供了完整而强大的技术栈,包括SQL查询、流式计算、机器学习和图算法组件,这些组件可以无缝整合到同一个应用中,足以应对复杂的计算。

(4)运行模式多样:Spark可运行于独立的集群模式中,或者运行于Haoop中,也可运行于Amazon EC2等云环境中,并且可以访问HDFS,Classdra、HBase、Hive等多种数据源。

二、Spark运行框架

1.基本概念

RDD:弹性分布式数据集(Resilient Distributed Dataset)是分布式内存的一个抽象概念,提供了一种高度受限的共享内存模型

DAG:有向无环图(Directed Acyclic Graph)反映RDD之间的依赖关系。

Executor:运行在工作节点(Worker Node)上的一个进程,负责运行任务,并为应用程序存储数据。

应用(Application):用户编写的Spark应用程序。

任务(Task):运行在Executor上的工作单元。

作业(Job):一个作业包含多个RDD及作用于相应RDD上的各种操作。

阶段(Stage):是作业的基本调度单位,一个作业会分为多组任务,每组任务被称为“阶段”或者也被称为“任务集”。

2.架构设计

与Hadoop MapReduce计算框架相比,Spark 所采用的Executor有两个优点:一是利用多线程来执行具体的任务(Hadoop MapReduce采用的是进程模型),减少任务的启动开销;二是Executor中有一个BlockManager存储模块,会将内存和磁盘共同作为存储设备(默认使用内存,当内存不够时,会写到磁盘)、当需要多轮迭代计算时,可以将中间结果存储到这个存储模型里,下次需要时,就可以直接读该存储模块里的数据,而不需要读写到HDFS等文件系统里,因而有效的减少了I/O开销,或者在交互式查询场景下,预先将表缓存到该存储系统上,从而提高读写IO性能。

总体而言,在Spark中,一个应用 ( Application)由一个任务控制节点( Driver)和若干个作业(Job)构成,一个作业由多个阶段( Stage)构成,一个阶段由多个任务(Task)组成。当执行一个应用时,任务控制节点Driver会向集群管理器( Cluster Manager )申请资源,启动Executor并向Executor发送应用程序代码和文件,然后在Executor上执行任务。运行结束后,执行结果会返回给任务控制节点Driver,或写到HDFS或其他数据库中。

3.Spark运行基本流程

(1)当一个Spark应用被提交时,首先需要为这个应用构建基本的运行环境,即由任务控制节点(Driver)创建一个SparkContext对象,由SparkContext负责与资源管理器( Cluster Manager)的通信以及进行资源的申请、任务的分配和监控等,SparkContext 会向资源管理器注册并申请运行Executor的资源,SparkContext可以看成是应用程序连接集群的通道。

(2)资源管理器为Eecutor分配资源,并启动Executor进程,Executor运行情况将随着“心跳“发送到资源管理器上。

(3) SparkContext根据RDD的依赖关系构建DAG图,并将DAG图提交给DAG调度器进行解析,将DAG图分解成多个“阶段”(每个阶段都是一个任务集 ),并且计算出各个阶段之间的依赖关系,然后把一个个“任务集”提交到底层的任务调度进行处理;Executor向SparkContext申请任务,任务调度器将任务分发给Executor运行,同时,SparkContext将应用程序代码发放给Executor。

(4)任务在Executor上运行,把执行结果反馈给任务调度器,然后反馈给DAG调度器,运行完毕后写入数据并释放所有资源。

三、RDD的设计与运行原理

1.RDD概述

一个RDD就是一个分布式对象集合,本质上是一个只读的分区记录集合

两种创建RDD的方法:
(1)基于稳定的物理存储。

​(2)通过在其他RDD上执行确定的转换操作(map,join,groupBy,filter等等)。

RDD提供的转换接口都是非常简单的,都是类似于map、filter、groupBy等粗粒度的数据装换操作,而不是针对某个数据项的细粒度修改。

2.RDD 的执行过程

(1)RDD读入外部数据源(或者内存中的集合)进行创建。

(2)RDD经过一系列的“转换”操作。每一次都会产生不同的RDD,供给下一个“转换”使用。

(3)最后一个RDD经“行动”操作进行处理,并输出到外部数据源(或者变成Scala集合或标量)。

当RDD在执行转换过程时,逻辑上它并没有计算,只是记录RDD之间的生成和依赖关系,即就是生成DAG图。只有当我们遇到“行动”操作时,Spark才会生成一个作业,向DAG调度器交作业,触发从起点开始的真正的计算。通过这种操作,着一系列RDD操作就可以实现通道化,避免了多次转换之间数据同步的等待,而且不用担心有过多的中间数据。

3.RDD之间的依赖关系

分为两种:宽依赖和窄依赖。他们之间的主要区别在于是否包含Shuffle操作。

(1)Shuffle操作

当我们在中转站不执行Shuffle操作时,我们可以看出来从上海到北京需要5小时,而当我们执行Shuffle操作时可以发现时间变长了(即数据要重新分发)。所以这会带来大量的磁盘I/O和网络开销。

(2)宽、窄依赖

窄依赖表现为一个父RDD的分区对应于一个子RDD分区,或多个父RDD的分区对应于一个子RDD的分区。

宽依赖则表现为存在一个父RDD的一个分区对应一个子RDD的多个分区。

以上是关于Spark的设计与运用原理的主要内容,如果未能解决你的问题,请参考以下文章

Spark学习——RDD的设计与运行原理

一文带你快速了解 Spark 架构设计与原理思想

Spark:RDD的设计与运行原理

一文带你了解 Spark 架构设计与原理思想

一文带你了解 Spark 架构设计与原理思想

一文带你了解 Spark 架构设计与原理思想