Spark学习
Spark执行原理自我理解:
(1) 首先程序有RDD Objects分解为DAG有向无环图
(2) 提交DAGScheduler,依据shuffer将DAG分解为一组taskset,即stages
(3) Taskset提交TaskScheduler,每一个taskset在分解为多个task,即一个task就是一个split分区
(4) Task就执行在worker上
Spark执行原理
(1)用户创建SparkContext对象,新创建的SparkContext会依据用户在编程的时候指定的參数或者系统默认的配置连接到ClusterManager。
(2)Cluster Manager会依据用户提交时的设值,(程序占用CPU的个数,内存的信息等等)来为我们详细的本次的程序分配计算资源。启动详细的Executor。
Driver会依据用户程序来进行这样的调度级别的一种Stage划分,但这边谈的stage的划分是高层调度器。Saprk在详细执行时分为高层调度和底层调度。高层调度是基于RDD的依赖。RDD的产生一般由前面RDD的详细某个操作中产生。第一次也能够从文件系统中读取一个内容就自己主动产生,也就是SparkContxt中产生,而后面总是依赖于前面的RDD产生。构成了继承和依赖关系。
假设说遇见宽依赖的时候,就划分成不同的Stage。每一个Stage会有一组全然同样的任务组成。这些任务分别作用待处理数据的不同分区。
(3)在Stage划分完毕和Task详细创建之后。Driver端会向详细的Executor发送详细的任务。Executor收到任务就会下载Task执行时依赖的库,包。准备好Task的
执行环境之后開始执行Task,执行时就是线程池中的线程执行的。
(4)在执行Task的过程中,会把执行状态汇报给Driver。Driver会依据收到的Task执行状态来处理不同的状态更新。Task本身依据我们之前不同的Stage划分。会把Task分为两种类型,一种是ShuffleMapTask,这个是对数据进行Shuffle,Shuffle的结果会保存在Executor所在节点的本地文件系统中。第二种是ResultTask。就是最后一个Stage。负责生成结果数据。Driver会不断地调用Task。将Task发送到Executor中执行,全部的Task都正确执行,或者超过执行次数的限制没有成功是会停止。正确执行了就会进入下一个Stage。
高层调度器DAGScheduler会帮助我们进行一定次数的重试,假设我们重试一定次数还没成功,那整个作业失败。
===================================================================================================================================
spark是一个分布式。基于内存的适合迭代计算的大数据计算框架。
基于内存,在一些情况下也会基于磁盘,spark计算时会优先考虑把数据放到内存中,应为数据在内存中就具有更好的数据本地性;假设内存放不下时,也会将少量数据放到磁盘上,它的计算既能够基于内存也能够基于磁盘,它适于不论什么规模的数据的计算。
Spark想用一个技术堆栈解决全部的大数据计算问题。大数据计算问题主要包括:交互式查询(基于shell和sql)、流处理(数据流入后直接进行处理)和批处理(基于Spark内核进行的一个RDD级别的编程,同一时候还包括图计算、机器学习的内容)。
眼下Spark支持的5中计算范式:流处理、SQL、R、图计算、机器学期等。
我们能够从三个方面去理解Spark。
1. 分布式
在生产环境下,是在分布式多台机器下去执行的。它会有几个特征:(1)我们的Spark会有一个Driver端。也就是所谓的client。我们自己编写的程序,要提交给集群;而在集群中有非常多机器,
整作业的执行实际上是执行在分布式的节点(默认一台机器是一个节点)中的。
Spark程序提交到Spark集群上进行执行,执行时要处理一批数据,因为它是分布式的。所以执行时不同的节点会处理一部分数据。
各个部分节点处理数据互不干扰。
所以,在做分布式时,就能够并行化。所以他就能够处理数据更快。
1. (主要)基于内存
Spark优先考虑使用内存,事实上是是对计算机资源最大化利用的一个物理基石。
在内存中能够放下时,最先考虑到内存中,放不下时放在磁盘上。
2. 擅长迭代式计算
擅长迭代式计算是Spark的真正精髓。在实际假设要对数据进行稍有价值的挖掘或是对数据进行稍有复杂度的一些挖掘。一定是要对数据进行具有多步奏的计算。这时候就要用到迭代式的计算,而Spark天生就是适用于分布式的主要基于内存的迭代式计算。Spark基于磁盘的迭代式计算会比hadoop快10x倍。而Spark基于内存的迭代式计算要比hadoop快100x倍。这里要提一下,当作业计算完第一个阶段,然后移动还有一个节点中进行计算。也就是所谓为的shuffle。并且能够重复的shuffle,并形成一个链条,这就是迭代。
我们写好的本地程序,提交到Driver上,他会提供一个接口即SparkContext,然后Driver会将我们的程序提交到集群上,各个work会并行计算处理我们的程序。Hadoop和Spark最根本的不同是迭代模型的不同,hadoop主要是两步map阶段和reduce阶段,进行完计算之后。就没有以后的阶段了,而Spark能够在计算完第一个阶段后,进行第二阶段计算。第二阶段计算完后进行第三阶段…也就是说。我们进行完一个阶段后,后面能够有非常多阶段的计算来完毕任务,而不是hadoop仅仅有map和reduce两个阶段这么僵硬。
因为它的这样的迭代式模型使得Spark更加强大和灵活。构造复杂算法时也更加easy。
在读取文件时,hadoop每次都是都是读取磁盘和写入磁盘,而Spark是基于内存的,大部分中间计算结果是保存在内存中,下一次计算是基于内存的计算结果的,所以节省了读取磁盘的时间。
Spark的快速执行除了基于内存。主要原因还是因为他的调度器(基于DAG之上的调度器,有高层调度器和底层调度器和容错)。
我们在本地开发好Spark文件,详细在单独的机器上提交程序,如上图圆圈中的都是Driver级别的,这些都是驱动整个程序执行的,Spark程序是会提交到集群中去执行的,他详细执行时是要靠Driver驱动来执行的。
而详细节点(如Spark worker)是一各个计算的节点work,而在计算时,要读取详细的数据,读取数据能够从HDFS。HBase,Hive或是传统的DB来源读取数据,处理数据时主要是利用线程池、线程复用的方式。处理完毕后,数据能够放在HDFS,HBase,Hive。DB。还能够直接返回直接给client。也就是正在执行程序的机器上的进程。
RDD
RDD:弹性分布式数据起。本生是对分布式计算一个抽象。
首先它是一个数据集(DataSet)。它会代表我们要处理的数据。可是它是分布式的,也就是分成非常多分片。分布在几百台或上千台机器上的。
在每一个节点上存储时默认这些数据都是放在内存中的。RDD代表了一些列的分片。而这些分片是在详细的不同节点上存储,默认优先在内存中存储。假设内存放不下,他会把一部分放在磁盘上进行存储。而这些对于我们用户来说是透明的。我们仅仅须要针对RDD进行计算和处理即可了。RDD本生会自己主动进行内存和磁盘的权衡和切换。这就是弹性之中的一个,其次,它基于Lineage的高效容错(他会更具血统继承关系来恢复执行出错情况,能够从上一个步奏进行又一次计算,而不会从第一个步奏又一次计算。效率非常高,以为不须要重头開始又一次计算),第三。task假设失败,会自己主动进行特定次数的重试(默认4次),第四。Stage假设失败会自己主动进行特定次数的重试(默认3次,仅仅计算失败的分片)。
以下我们讲下缓存的时机:
(1)计算特别耗时
(2)计算链条已经非常长了
(3)Shuffle之后(冲其它地方抓数据后)
(4)ChechPoint之前(chechPoint是当前作业执行后,再触发一个作业)
RDD本生会有一些列的数据分片,一个RDD在逻辑上就代表了顶层的一个文件或目录,但实际上它是依照分区(partition)分为多个分区。分区会放在Spark集群中不同的机器的节点上。而RDD本生又包括了对函数的计算。