3.Spark设计与运行原理,基本操作


一.Spark已打造出结构一体化、功能多样化的大数据生态系统,请用图文阐述Spark生态系统的组成及各组件的功能。

1. Spark Core
Spark Core是整个BDAS的核心组件,是一种大数据分布式处理框架,不仅实现了MapReduce的算子map函数和reduce函数及计算模型,还提供如filter、join、groupByKey等更丰富的算子。
Spark将分布式数据抽象为弹性分布式数据集(RDD),实现了应用任务调度、RPC、序列化和压缩,并为运行在其上的上层组件提供API。其底层采用Scala函数式语言书写而成,并且深度借鉴Scala函数式的编程思想,提供与Scala类似的编程接口。

2. Mesos
Mesos是Apache下的开源分布式资源管理框架,被称为分布式系统的内核,提供了类似YARN的功能,实现了高效的资源任务调度。

3. Spark Streaming
Spark Streaming是一种构建在Spark上的实时计算框架,它扩展了Spark处理大规模流式数据的能力。其吞吐量能够超越现有主流流处理框架Storm,并提供丰富的API用于流数据计算。

4. MLlib
MLlib是Spark对常用的机器学习算法的实现库,同时包括相关的测试和数据生成器。MLlib目前支持4种常见的机器学习问题:二元分类、回归、聚类以及协同过滤,还包括一个底层的梯度下降优化基础算法。

5. GraphX
GraphX是Spark中用于图和图并行计算的API,可以认为是GraphLab和Pregel在Spark (Scala)上的重写及优化,与其他分布式图计算框架相比,GraphX最大的贡献是,在Spark上提供一栈式数据解决方案,可以方便、高效地完成图计算的一整套流水作业。

6. Spark SQL
Shark是构建在Spark和Hive基础之上的数据仓库。它提供了能够查询Hive中所存储数据的一套SQL接口,兼容现有的Hive QL语法。熟悉Hive QL或者SQL的用户可以基于Shark进行快速的Ad-Hoc、Reporting等类型的SQL查询。由于其底层计算采用了Spark,性能比Mapreduce的Hive普遍快2倍以上,当数据全部存储在内存时,要快10倍以上。2014年7月1日,Spark社区推出了Spark SQL,重新实现了SQL解析等原来Hive完成的工作,Spark SQL在功能上全覆盖了原有的Shark,且具备更优秀的性能。

7. Alluxio
Alluxio(原名Tachyon)是一个分布式内存文件系统,可以理解为内存中的HDFS。为了提供更高的性能,将数据存储剥离Java Heap。用户可以基于Alluxio实现RDD或者文件的跨应用共享,并提供高容错机制,保证数据的
可靠性。

8. BlinkDB
BlinkDB是一个用于在海量数据上进行交互式SQL的近似查询引擎。它允许用户在查询准确性和查询响应时间之间做出权衡,执行相似查询。

二.请详细阐述Spark的几个主要概念及相互关系:

 Master, Worker;  RDD,DAG; Application, job,stage,task; driver,executor,Claster Manager

  DAGScheduler, TaskScheduler.

1.Master-Worker模式的核心思想是在于Master进程和Worker进程各自分担各自的任务,协同完成信息处理的模式
使用一个图例来简单描述一下:

 

 


如图所示Master-Worker的工作机制就是Master接收到了一个任务,对任务进行拆分,并且分配给各个Worker,让各个Worker之间各自运行各自的子任务,最后Worker们的返回结果交给Master进行汇总并且最后返回给任务的发起方.

Master-Worker是一种并行模式,Master是主要进程,Master中有维护着一个Worker进程队列.Master把一个大的而且复杂的业务拆分成若干小的业务,只要是互不影响的都可以分而治之相互独立.可以通过多线程或多进程甚至多机联合计算,把拆分后的小业务交给更多的CPU或机器处理,通过并发/并行的方式提高整体业务的运算速度,压榨系统性能来提高效率.

2.

RDD算子构建了RDD之间的关系,整个计算过程形成了一个由RDD和关系构成的DAG。

简单理解为点和线构成图。

点是某种数据结构,spark计算框架的点就是RDD(或者stage)

线就是关联关系,spark计算框架的线就是RDD算子(或者宽依赖算子)

宽依赖:父RDD的分区被子RDD的多个分区使用 例如 groupByKey、reduceByKey、sortByKey等操作会产生宽依赖,会产生shuffle,DAG中根据窄依赖划分stage边界。

窄依赖:父RDD的每个分区都只被子RDD的一个分区使用 例如map、filter、union等操作会产生窄依赖)

它们的执行过程是这样的:

1,任务触发是有Action 算子触发(详见上一篇算子),查找的入口就是action算子前的最后一个RDD(finalRDD图中:RDD G),开始遍历DAG。

2,getShuffleDependencies遍历宽依赖关系,遇到窄依赖放入HashMap visit,遇到宽依赖时直接跳转到第3步。如果结束返回完成。

3,getMissingParentStages遍历窄依赖,创建resultstage(方法createResultStage),遇到窄依赖放入HashMap visit,遇到宽依赖递归第2步骤 。如果结束跳入上一步继续检索。

4,遇到可计算的stage (finalStage ),可计算指的是stage中所有RDD都可以寻址到内存或磁盘,提交stage任务到taskscheduler,taskscheduler负责分发任务到集群的worker中计算。如果结束跳入上一步继续检索。

3.

RDD任务切分中间分为:Application、Job、Stage和Task

(1)Application:初始化一个SparkContext即生成一个Application;

(2)Job:一个Action算子就会生成一个Job;

(3)Stage:Stage等于宽依赖的个数加1;

(4)Task:一个Stage阶段中,最后一个RDD的分区个数就是Task的个数。

4.

Driver:驱动程序

    Spark中的Driver即运行上述Application的Main()函数并且创建SparkContext,其中创建SparkContext的目的是为了准备Spark应用程序的运行环境。在Spark中由SparkContext负责和ClusterManager通信,进行资源的申请、任务的分配和监控等;当Executor部分运行完毕后,Driver负责将SparkContext关闭。通常SparkContext代表Driver,如下图所示。

 

 

Cluster Manager:资源管理器

    指的是在集群上获取资源的外部服务,常用的有:Standalone,Spark原生的资源管理器,由Master负责资源的分配;Haddop Yarn,由Yarn中的ResearchManager负责资源的分配;Messos,由Messos中的Messos Master负责资源管理。

Executor:执行器

    Application运行在Worker节点上的一个进程,该进程负责运行Task,并且负责将数据存在内存或者磁盘上,每个Application都有各自独立的一批Executor,如下图所示。

 

 

DAGScheduler:有向无环图调度器

基于DAG划分Stage 并以TaskSet的形势提交Stage给TaskScheduler;负责将作业拆分成不同阶段的具有依赖关系的多批任务;最重要的任务之一就是:计算作业和任务的依赖关系,制定调度逻辑。在SparkContext初始化的过程中被实例化,一个SparkContext对应创建一个DAGScheduler。

 

 

TaskScheduler:任务调度器

将Taskset提交给worker(集群)运行并回报结果;负责每个具体任务的实际物理调度。如图所示。

 

 三.在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转换关系图如下:

 

 

 

posted @ 2022-03-09 16:36  LYH2022  阅读(45)  评论(0编辑  收藏  举报