3.Spark设计与运行原理,基本操作
1.Spark已打造出结构一体化、功能多样化的大数据生态系统,请用图文阐述Spark生态系统的组成及各组件的功能。
Spark Core:
Spark Core 是整个BDAS 生态系统的核心组件,是一个分布式大数据处理框架。Spark Core提供了多种资源调度管理,通过内存计算、有向无环图(DAG)等机制保证分布式计算的快速,并引入了RDD 的抽象保证数据的高容错性,其重要特性描述如下:
- Spark Core提供了多种运行模式,不仅可以使用自身运行模式处理任务,如本地模式、Standalone,而且可以使用第三方资源调度框架来处理任务,如YARN、MESOS等。相比较而言,第三方资源调度框架能够更细粒度管理资源。
- Spark Core提供了有向无环图(DAG)的分布式并行计算框架,并提供内存机制来支持多次迭代计算或者数据共享,大大减少迭代计算之间读取数据的开销,这对于需要进行多次迭代的数据挖掘和分析性能有极大提升。另外,在任务处理过程中移动计算而非移动数据,RDDPartition 可以就近读取分布式文件系统中的数据块到各个节点内存中进行计算。
- 在Spark 中引入了RDD的抽象,它是分布在一组节点中的只读对象集合,这些集合是弹性的,如果数据集一部分丢失,则可以根据“血统”对它们进行重建,保证了数据的高容错性。
Spark SQL:
Spark SQL允许开发人员直接处理RDD,同时也可查询Hive、HBase等外部数据源。Spark SQL的一个重要特点是其能够统一处理关系表和RDD,使得开发人员可以轻松地使用SQL命令进行查询,并进行更复杂的数据分析。
Spark Mlib:
MLlib提供了常用机器学习算法的实现,包括聚类、分类、回归、协同过滤等,降低了机器学习的门槛,开发人员只要具备一定的理论知识就能进行机器学习的工作。
GraphX:
GraphX是Spark中用于图计算的API,可认为是Pregel在Spark上的重写及优化,Graphx性能良好,拥有丰富的功能和运算符,能在海量数据上自如地运行复杂的图算法。
2.请详细阐述Spark的几个主要概念及相互关系:
Master, Worker; RDD,DAG; Application, job,stage,task; driver,executor,Claster Manager; DAGScheduler, TaskScheduler.
master和worker:
master节点常驻master守护进程,负责管理worker节点,我们从master节点提交应用。
worker节点常驻worker守护进程,与master节点通信,并且管理executor进程。

driver进程就是应用的main()函数并且构建sparkContext对象,当我们提交了应用之后,便会启动一个对应的driver进程,driver本身会根据我们设置的参数占有一定的资源。driver可以运行在master上,也可以运行worker上。driver首先会向集群管理者(standalone、yarn,mesos)申请spark应用所需的资源,也就是executor,然后集群管理者会根据spark应用所设置的参数在各个worker上分配一定数量的executor,每个executor都占用一定数量的cpu和memory。在申请到应用所需的资源以后,driver就开始调度和执行我们编写的应用代码了。driver进程会将我们编写的spark应用代码拆分成多个stage,每个stage执行一部分代码片段,并为每个stage创建一批tasks,然后将这些tasks分配到各个executor中执行。
executor进程宿主在worker节点上,一个worker可以有多个executor。每个executor持有一个线程池,每个线程可以执行一个task,executor执行完task以后将结果返回给driver,
每个executor执行的task都属于同一个应用。
Claster Manager负责整个程序的资源调度,目前的主要调度器有:YARN、Spark Standalone、Mesos
RDD 是 Spark 的计算模型。RDD 叫做弹性的分布式数据集合,是 Spark 中最基本的数据抽象,它代表一个不可变、只读的,被分区的数据集。操作 RDD 就像操作本地集合一样,有很多的方法可以调用,使用方便,而无需关心底层的调度细节。
DAG是有向无环图:有方向,无闭环,代表着数据的流向,这个DAG的边界则是Action方法的执行。
构建RDD形成DAG遇到Action的时候,前面的stage先提交,提交完成之后再交给下游的数据,在遇到TaskScheduler,这个时候当我们遇到Action的方法的时候,我们就会让Master决定让哪些Worker来执行这个调度,但是到了最后我们真正的传递的时候,我们用的是Driver给Worker传递数据(其实是传递到Excutor里面,这个里面执行真正的业务逻辑),Worker中的Excutor只要启动,则此后就和Master没有多大关系了。
Application, job,stage,task:
RDD任务切分中间分为:Application、Job、Stage和Task。
Application:初始化一个SparkContext即生成一个Application。
Job: Job是用户程序一个完整的处理流程,是逻辑的叫法。
Stage: 一个Job可以包含多个Stage,Stage之间是串行的,State的触发是由一些shuffle,reduceBy,save动作产生的
Task: 一个Stage可以包含多个task,比如sc.textFile("/xxxx").map().filter(),其中map和filter就分别是一个task。每个task的输出就是下一个task的输出。
DAGScheduler, TaskScheduler:
DAGScheduler:面向调度阶段的任务调度器,负责接收spark应用提交的作业,根据RDD的依赖关系划分调度阶段,并提交调度阶段给TaskScheduler。
TaskScheduler:面向任务的调度器,它接受DAGScheduler提交过来的调度阶段,然后把任务分发到work节点运行,由Worker节点的Executor来运行该任务。
在Spark中一个核心的是模块就是调度器,在spark中Scheduler有两种TaskScheduler(是低级的调度器接口),DagScheduler(是高级的调度器接口);我们在创建SparkContext对象的时候,sparkcontext内部就会创建TaskScheduler和DagScheduler,
3.在PySparkShell尝试以下代码,观察执行结果,理解sc,RDD,DAG。请画出相应的RDD转换关系图。
>>> sc >>> lines = sc.textFile("file:///home/hadoop/my.txt") >>> lines >>> words=lines.flatMap(lambda line:line.split()) >>> words >>> wordKV=words.map(lambda word:(word,1)) >>> wordKV >>> wc=wordKV.reduceByKey(lambda a,b:a+b) >>> wc >>> cs=lines.flatMap(lambda line:list(line)) >>> cs >>> cKV=cs.map(lambda c:(c,1)) >>> cKV >>> cc=cKV.reduceByKey(lambda a,b:a+b) >>> cc >>> lines.foreach(print) >>> words.foreach(print) >>> wordKV.foreach(print) >>> cs.foreach(print) >>> cKV.foreach(print) >>> wc.foreach(print) >>> cc.foreach(print)
RDD转换关系图: