赞
踩
Spark
Spark是基于内存的计算引擎,主要用于进行高速的计算,可以满足用户对于计算时间的需求。Spark轻快灵巧。Spark分为以下几个组件
1.SparkCore:Spark的处理核心,用于执行所有的相关计算
2.SparkSQL:将用户下发的SQL指令转译为SparkCore可以识别的命令进行计算,所以SparkSQL引擎其实可以理解为是翻译器
3.StructuredStreaming:流处理引擎
4.SparkStreaming:批处理引擎
5.其他:主要是算法库和编程的软件库
批处理和流处理的区别:
1.从处理的数据角度来说,批处理一般倾向于累积一定的数据量之后才会去进行数据的计算和处理。流处理一般是实时的对获取到的数据进行处理。
2.从延迟性上来说,批处理的延迟较高,流处理基本无延迟。
3.从数据吞吐量上来讲,批处理较高,流处理比较低。
4.流处理具有严格的时间顺序性,而批处理没有。其实指的就是流处理在处理 数据的时候,是绝对公平的,FIFO。
5.批处理在执行操作之前,会要求数据先行存储在HDFS上或者是数据需要有一个固定的数据源。流处理实时从各个数据源收集数据做计算。
6.批处理的应用执行完成之后就会被关闭,而流处理除非用户手工关闭,否则会一直持续运行。
7.如果用户对于数据的延迟要求不高,但是要求计算的吞吐量足够大的时候,我们一般选择批处理,如果用户对于延迟要求极高,并且数据量不大,那么一般建议使用流处理。
8.所以流处理一般适合用于数据量不大,对延迟敏感,并且需要长期持续的应用。批处理一般适合用于数据量较大,对延迟不敏感,并且执行完成之后就会马上注销的应用。
RDD
所谓说RDD,官方解释是弹性分布式数据集,所谓弹性指的就是数据集的大小可以变化,不是一个固定值,所谓分布式,指的就是一个大的数据集被切分进行计算。那么实际上RDD就是由一个大的数据集切分所构成的小的数据集合,只不过该数据集合内的数据往往都是存在有一定的关联性的。
RDD存在有依赖关系和父子关系。我们可以使用父RDD得到子RDD
RDD的依赖存在有宽依赖和窄依赖。所谓宽依赖指的是子RDD的所有分区都依赖于父RDD的所有分区。所谓窄依赖,就是子RDD的所有分区不依赖于父RDD的所有分区、
我们遇到宽依赖的时候,就会被拆分成窄依赖。
在Spark中,由于其是基于内存的计算引擎,所以计算过程 中,出现相关的内存紧张是很正常的事情,所以为了节约内存,我们选择使用两种算子,一种叫做action,一种叫做Transformation算子。
其中action算子指的就是执行算子,也就是具有实质的操作动作的计算。
Transformation算子指的是逻辑计算的算子
两者的区别在于,action算子必须要有对应的动作去相应,比如print。
Transformation算子是逻辑计算的,所以其结果一般都是缓存在内存中的,不会对外部显示或者是有相关的显示类的操作。
由于内存紧张,所以我们一般来说,是不会计算Transformation算子的,因为一旦该类型算子计算,那么就势必会产生结果数据占用内存。所以我们一般会选择当遇到Transformation算子 的时候,跳过计算。那么这样就可以节省一部分的临时内存占用。每当遇到action算子的时候 ,那么就必须要有动作 ,为了满足动作,就必须从该action算子开始连带之前的未计算的Transformation算子 一起执行。
虽然在这个时刻,我们执行 Transformation算子需要占用 内存。但是一旦计算完action算子之后,连带之前Transformation算子占用的内存就会立即释放。所以我们跳过Transformation算子的操作,其实只是为了减少对内存的占用时间
SparkCore任务执行流程(简单版)
1.用户向Client提交请求,Client将请求转发给Driver。
2.Driver收到请求并且联系RM要求拉起AppMaster
3.AppMaster启动之后,根据应用需要消耗的资源向RM申请
4.RM收到请求之后,会联系NM要求拉起Executor。
5.Executor启动之后,会联系Driver注册,Driver会下发task给Executor
6.Executor执行完成之后反馈结果给Driver。Driver整理结果,给Client最终反馈给用户。
7.AppMaster自我注销,Driver自我注销。关闭应用。Executor自我注销,由NM回收资源并且上报RM。
在 Spark中,和MapReduce有很大的不同,首先是AppMaster,在MR中,AppMaster是由Client提交的应用上传到RM中,由APPManager下发,但是在 Spark中AppMaster应用是由Driver下发的。MR中的AppMaster需要启动后注册,Spark中不需要。在MR中AppMaster需要做资源分配申请、任务管理下发,那么在 Spark中AppMaster只负责申请资源,任务管理由Driver来做。MR中的Container由一个任务独享。在Spark中,Container被切分为Executor分给任务共享。
Driver是Spark中新加入的一个组件,它主要负责了任务的管理和下发。其最大的作用就是划分DAG(运行规划—有向无环图)通过划分DAG,Spark可以在计算的时候以最小的开销去执行相关的计算。
DAG将用户提交的应用切分为了四部分分别是:Application、job、Stage、Task
1.Application:用户提交的一个应用就是一个Application
2.Job:每当遇到Action算子的时候,就被切分为job
3.Stage(阶段):当宽依赖拆分为窄依赖的时候,就会形成stage
注:拆依赖的原理:在进行实际的计算时,由于宽依赖中,子RDD中的所有分区都要依赖于父RDD的所有分区,所以一旦父RDD的计算中只要卡住任意一个分区就会导致所有的分区全部卡住,并且子RDD中的所有分区都会重复加载相同的数据,不仅占用的内存大,时间也会很久。所以为了防止这种大量占用内存的行为 ,我们指定了宽依赖拆窄依赖的行为,其实严格意义上来讲,宽依赖拆分窄依赖并没有做,而是将宽依赖的执行拆分成了两个执行阶段,仅当父RDD中的所有分区全部计算完毕的时候,子RDD的计算才能开始,这样做就可以加快内存的释放速度。即使父RDD的计算卡住,其占用的内存量也会大大减少,影响尽可能多的降低。
4.task:任务,具体的执行
当一个应用提交上来的时候,Driver按照如上的4个切分方式对任务切分之后,构成的就是DAG
SparkCore任务执行流程
1.用户向Client提交应用。Client收到应用之后会将应用中的Driver抽取出来,并且拉起。(但是Driver的拉起并不是在容器中的,而是在收到请求的Client所在的主机的内存中)。
2.Driver启动之后,首先会联系RM中的APPManager,请求分配jobID。之后获取到JobID以后,Driver会首先切分数据形成RDD,之后读取应用,将应用中的算子划分为DAG。
3.下一步Driver会将应用中的AppMaster程序抽取出来,并且交给RM中的APPManager,APPManager收到请求之后,首先会联系RS查询集群中节点资源负载。选择压力最小的节点,分配资源的使用权给APPManager,APPManager获取使用权之后会要求NM拉起容器,并且启动AppMaster。
4.AppMaster启动之后首先会计算应用需要消耗的资源,然后向RM中的RS申请资源。AppMaster无需注册。
5.RM中的RS收到请求之后,会根据负载,要求集群中压力最小的NM启动Container。并且将Container切分为Executor。
6.由于Executor并不是由应用内的组件(Driver和AppMaster)启动的,所以对于Driver来说,它并不知道Executor的启动情况,所以在Executor启动之后,需要和Driver进行注册。
7.Driver收到注册请求之后,会检测自身的DAG。通过任务管理器,读取应用,遇到Transformation算子则跳过,遇到Action算子,则将之前所有未执行的Transformation算子打包和Action算子一起下发到Executor中进行计算。
8.Executor计算完成之后,会反馈结果给Driver,Driver整合结果,并且反馈给Client,之后给用户。
9.任务执行完成之后,Executor自我注销,资源被NM回收,并且通过NM周期性的心跳上报给RM中的RS,AppMaster自我注销关闭。Driver自我注销,但是在注销前需要通告RM中的APPManager一条消息,标识任务执行完毕。
SparkSQL:用于处理SQL指令的翻译器。其受到用户的SQL指令 ,将指令转化为SparkCore可以识别的命令格式,进行计算执行,并且反馈相关的结果。
Core作为处理核心,可以对多种类型的数据进行计算,但是在SQL中,数据往往都是由结构化数据构成,所以RDD虽然可以做SQL的数据加载,但是并不是特别的适合。所以,我们提出了DataSet和DataFrame两种形式的数据格式。
序列化和反序列化
在Spark中,为了节约内存,我们计算出来的结果一般都是以2进制的形式存储的。但是2进制编码SparkCore是无法识别的,这样做虽然可以大幅度的节约内存,但是为了能够让Core计算,每次计算前都需要将数据从2进制转换为Core可以识别的编码格式,那么计算之后,为了节约内存存储,我们也要将数据转化为2进制存储。那么2进制到Core可以识别的格式之间的来回转换就叫做序列化和反序列化。虽然这样做,可以节约内存,但是序列化和反序列化的操作需要消耗时间和CPU资源。所以DataSet直接按照2进制存储数据,并且Core在计算DataSet的时候,可以直接针对2进制做计算,那么就不在需要序列化和反序列化操作了。节约了大量的时间,资源,并且内存仍然节省了大部分。
刷新:
增量刷新:就是对数据库中新增加的数据进行刷新操作
全量刷新:就是对数据库中所有的数据进行刷新(重载)操作
SparkStreaming
本质上来讲SparkStreaming并不是一个严格意义上的流处理引擎。作为流处理,第一个需要保证的就是实时性,数据进入引擎之后,就会被立即执行计算。但是SparkStreaming它会将数据累积一段时间,等到一定的数据量之后再进行计算,这也就导致了,其延迟增加,一般来说,SparkStreaming处理数据有若干毫秒到秒级的延迟。但是Storm等流处理引擎延迟为亚秒级。
SparkStreaming和Storm
1.前者是类流处理引擎,Storm是实时流处理引擎。
2.由于SparkStreaming的特性,导致其吞吐量比Storm高,但是延迟也比Storm高
3.SparkStreaming会将作业进行留存,到一定量之后再计算,Storm会实时计算。
4.从延迟上来说,SparkStreaming处理数据有若干毫秒到秒级的延迟。但是Storm等流处理引擎延迟为亚秒级。
5.如果用户的业务对于延迟要求并不敏感,而数据量偏大,那么一般建议选用SparkStreaming,如果用户的业务对于延迟要求极高,那么就使用Storm。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。