Spark源码学习(4)——Scheduler

合集下载

Spark Streaming作业提交源码分析数据处理篇

Spark Streaming作业提交源码分析数据处理篇
Spark Streaming作业提交源码分析数据处理篇
在调用StreamingContext的start函数的时候,会调用JobScheduler的start函数。而JobScheduler的start函数会启 动ReceiverTracker和jobGenerator。
在启动jobGenerator的时候,系统会根据这次是从Checkpoint恢复与否分别调用restart和startFirstTime函数。
是allocateBlocksToBatch函数,其定义如下:
def allocateBlocksToBatch(batchTime: Time): Unit = synchronized { if (lastAllocatedBatchTime == null || batchTime > lastAllocatedBatchTime) { val streamIdToBlocks = streamIds.map { streamId => (streamId, getReceivedBlockQueue(streamId).dequeueAll(x => true)) }.toMap val allocatedBlocks = AllocatedBlocks(streamIdToBlocks) writeToLog(BatchAllocationEvent(batchTime, allocatedBlocks)) timeToAllocatedBlocks(batchTime) = allocatedBlocks lastAllocatedBatchTime = batchTime allocatedBlocks } else { // This situation occurs when: // 1. WAL is ended with BatchAllocationEvent, but without BatchCleanupEvent, // possibly processed batch job or half-processed batch job need to be processed // again, so the batchTime will be equal to lastAllocatedBatchTime. // 2. Slow checkpointing makes recovered batch time older than WAL recovered // lastAllocatedBatchTime. // This situation will only occurs in recovery time. logInfo(s"Possibly processed batch $batchTime need to be processed again in WAL recovery") }

python的scheduler用法 -回复

python的scheduler用法 -回复

python的scheduler用法-回复Python的scheduler用法在编程中,定时任务是一项非常重要的功能。

Python中的scheduler模块为我们提供了一种简单而强大的方法来执行定时任务。

scheduler模块基于时间触发(time-based trigger),可以根据我们设定的时间或间隔来执行任务。

本文将详细介绍scheduler模块的用法,一步一步回答关于Python的scheduler用法的问题。

问题1:scheduler模块是什么?scheduler模块是Python标准库中的一个模块,它提供了一个通用的定时触发框架,可以根据设定的时间或间隔触发任务的执行。

scheduler模块的主要作用是帮助我们管理定时任务,使其按照我们的要求定时执行。

问题2:如何安装scheduler模块?在使用Python标准库中的scheduler模块之前,我们无需安装任何额外的软件或扩展包。

因为scheduler模块是Python的标准库之一,所以它已经包含在Python的安装包中。

只需要确保Python版本正确安装,并且运行环境正确配置即可。

问题3:如何导入scheduler模块?在使用scheduler模块之前,我们需要在Python脚本中导入该模块。

可以使用如下代码导入scheduler模块:import schedule问题4:scheduler模块的基本用法是什么?scheduler模块的基本用法分为三个步骤:1. 创建一个scheduler对象2. 定义定时任务3. 运行scheduler下面我们将逐步介绍这三个步骤。

第一步:创建scheduler对象为了使用scheduler模块,我们需要先创建一个scheduler对象。

可以使用如下代码创建一个scheduler对象:pythonscheduler = schedule.scheduler()第二步:定义定时任务在scheduler对象创建完成后,我们可以使用其提供的方法来定义定时任务。

Spark集群启动之Master、Worker启动流程源码分析

Spark集群启动之Master、Worker启动流程源码分析

Spark集群启动之Master、Worker启动流程源码分析Spark集群启动Master可以使用脚本启动:start-master,shell脚本细节自行查看。

最终启动命令为:Java -cp /home/daxin/bigdata/spark/conf/:/home/daxin/bigdata/spark/jars/*:/home/daxin/bigdata/Hadoop/et c/hadoop/ -Xmx1g -XX:MaxPermSize=256m org.apache.spark.deploy.master.Master --host node --port 7077 --webui-port 8080最终转换为java命令启动Master的过程,所以我们就需要查看一下Master的main方法代码如下:[java] view plain copy 在CODE上查看代码片派生到我的代码片val systemName = "sparkMaster"private val actorName = "Master"/*** spark-class脚本调用,启动master** @param argStrings*/def main(argStrings: Array[String]) {SignalLogger.register(log)//参数配置准备val conf = new SparkConfval args = new MasterArguments(argStrings, conf)//创建actorSystem// (actorSystem, boundPort, portsResponse.webUIPort, portsResponse.restPort)val (actorSystem, _, _, _) = startSystemAndActor(args.host, args.port, args.webUiPort, conf) actorSystem.awaitTermination()}通过代码可以可以知道调用startSystemAndActor方法完成ActorSystem和Actor的创建。

spark原理详解

spark原理详解

spark原理详解Spark是基于内存的大数据处理框架,它提供了高性能和高扩展性的数据处理能力。

本文将详细介绍Spark的工作原理。

Spark的核心概念是弹性分布式数据集(Resilient Distributed Dataset,简称RDD)。

RDD是Spark中最基本的数据抽象,它是一个可以并行处理和分布式存储的数据集合。

RDD可以通过各种数据源(如Hadoop HDFS、HBase等)进行创建,并支持多次转换操作来构建一个完整的数据处理流程。

在Spark中,数据处理的基本单位是RDD。

RDD可以被分区成多个小的任务,然后分配给集群上的节点进行并行处理。

每个节点上的任务会独立地读取和处理数据,并将结果合并到一个新的RDD中。

这种方式可以提高数据处理的速度和效率。

Spark采用了内存计算的方式来提高性能。

它将数据存储在内存中,以便更快地访问和处理。

Spark还采用了一种称为“弹性分布式数据集”的数据结构,可以在内存和磁盘之间进行数据交换,从而充分利用集群中的资源。

Spark还提供了一种称为DAG调度的机制来管理任务的执行。

DAG(有向无环图)是一种任务之间依赖关系的图形表示。

Spark会根据任务的依赖关系构建一个DAG,然后根据DAG中的依赖关系调度和执行任务。

通过DAG调度,Spark可以在执行任务时进行优化和并行化,以提高整体的执行效率。

此外,Spark还提供了一些高级特性来增强数据处理的能力。

例如,它支持内置的机器学习和图处理库,可以方便地进行机器学习和图分析等高级数据处理任务。

总结来说,Spark是一个基于内存的大数据处理框架,通过RDD、内存计算和DAG调度等机制,提供了高性能和高扩展性的数据处理能力。

它可以方便地处理大规模数据,并支持各种高级数据处理任务。

python的scheduler用法 -回复

python的scheduler用法 -回复

python的scheduler用法-回复Python的scheduler用法是一种非常强大和灵活的调度工具,它允许我们按照预定的时间安排任务的执行。

在本文中,我们将逐步回答关于Python的scheduler用法的问题,并提供示例说明。

1. 什么是scheduler?Scheduler是一种工具,它可以按照我们指定的时间进行任务的调度和执行。

它具有非常灵活的功能,可以适应各种不同的需求和场景。

2. 如何安装scheduler?Python的scheduler库非常简单,可以使用pip进行安装。

只需在命令行中运行以下命令即可安装:pip install schedule3. 如何引入scheduler库?在使用scheduler之前,我们需要在Python脚本中导入scheduler 库。

可以使用以下代码:pythonimport scheduleimport time4. 如何使用scheduler执行一次性任务?scheduler提供了`do`方法来安排一次性的任务执行。

下面是一个示例代码,演示如何在指定的时间执行一次性任务:pythondef job():print("任务正在执行...")schedule.every().day.at("10:30").do(job)while True:schedule.run_pending()time.sleep(1)在上述示例中,任务`job`被安排在每天的10:30执行。

要注意的是,我们需要使用`run_pending`方法来持续运行调度器,以便执行任务。

5. 如何使用scheduler按固定时间间隔执行任务?scheduler还提供了`every`方法来安排按固定时间间隔执行的任务。

下面是一个示例代码,演示如何每隔一段时间执行任务:pythondef job():print("任务正在执行...")schedule.every(5).seconds.do(job)while True:schedule.run_pending()time.sleep(1)在上述示例中,任务`job`被安排每隔5秒执行一次。

YARN调度器(Scheduler)详解

YARN调度器(Scheduler)详解

YARN调度器(Scheduler)详解理想情况下,我们应⽤对Yarn资源的请求应该⽴刻得到满⾜,但现实情况资源往往是有限的,特别是在⼀个很繁忙的集群,⼀个应⽤资源的请求经常需要等待⼀段时间才能的到相应的资源。

在Yarn中,负责给应⽤分配资源的就是Scheduler。

其实调度本⾝就是⼀个难题,很难找到⼀个完美的策略可以解决所有的应⽤场景。

为此,Yarn提供了多种调度器和可配置的策略供我们选择。

YARN架构如下:ResourceManager(RM):负责对各NM上的资源进⾏统⼀管理和调度,将AM分配空闲的Container运⾏并监控其运⾏状态。

对AM申请的资源请求分配相应的空闲Container。

主要由两个组件构成:调度器(Scheduler)和应⽤程序管理器(Applications Manager)。

调度器(Scheduler):调度器根据容量、队列等限制条件(如每个队列分配⼀定的资源,最多执⾏⼀定数量的作业等),将系统中的资源分配给各个正在运⾏的应⽤程序。

调度器仅根据各个应⽤程序的资源需求进⾏资源分配,⽽资源分配单位是Container,从⽽限定每个任务使⽤的资源量。

Scheduler不负责监控或者跟踪应⽤程序的状态,也不负责任务因为各种原因⽽需要的重启(由ApplicationMaster负责)。

总之,调度器根据应⽤程序的资源要求,以及集群机器的资源情况,为⽤程序分配封装在Container中的资源。

调度器是可插拔的,例如CapacityScheduler、FairScheduler。

(PS:在实际应⽤中,只需要简单配置即可)应⽤程序管理器(Application Manager):应⽤程序管理器负责管理整个系统中所有应⽤程序,包括应⽤程序提交、与调度器协商资源以启动AM、监控AM运⾏状态并在失败时重新启动等,跟踪分给的Container的进度、状态也是其职责。

ApplicationMaster是应⽤框架,它负责向ResourceManager协调资源,并且与NodeManager协同⼯作完成Task的执⾏和监控。

spark学习路线及参考课程

spark学习路线及参考课程

spark学习路线及参考课程⼀、Scala编程详解:第1讲-Spark的前世今⽣第2讲-课程介绍、特⾊与价值第3讲-Scala编程详解:基础语法第4讲-Scala编程详解:条件控制与循环第5讲-Scala编程详解:函数⼊门第6讲-Scala编程详解:函数⼊门之默认参数和带名参数第7讲-Scala编程详解:函数⼊门之变长参数第8讲-Scala编程详解:函数⼊门之过程、lazy值和异常第9讲-Scala编程详解:数组操作之Array、ArrayBuffer以及遍历数组第10讲-Scala编程详解:数组操作之数组转换第11讲-Scala编程详解:Map与Tuple第12讲-Scala编程详解:⾯向对象编程之类第13讲-Scala编程详解:⾯向对象编程之对象第14讲-Scala编程详解:⾯向对象编程之继承第15讲-Scala编程详解:⾯向对象编程之Trait第16讲-Scala编程详解:函数式编程第17讲-Scala编程详解:函数式编程之集合操作第18讲-Scala编程详解:模式匹配第19讲-Scala编程详解:类型参数第20讲-Scala编程详解:隐式转换与隐式参数第21讲-Scala编程详解:Actor⼊门⼆、课程环境搭建:第22讲-课程环境搭建:CentOS 6.5集群搭建第23讲-课程环境搭建:Hadoop 2.4.1集群搭建第24讲-课程环境搭建:Hive 0.13搭建第25讲-课程环境搭建:ZooKeeper 3.4.5集群搭建第26讲-课程环境搭建:kafka_2.9.2-0.8.1集群搭建第27讲-课程环境搭建:Spark 1.3.0集群搭建三、Spark核⼼编程:第28讲-Spark核⼼编程:Spark基本⼯作原理与RDD第29讲-Spark核⼼编程:使⽤Java、Scala和spark-shell开发wordcount程序第30讲-Spark核⼼编程:wordcount程序原理深度剖析第31讲-Spark核⼼编程:Spark架构原理第32讲-Spark核⼼编程:创建RDD实战(集合、本地⽂件、HDFS⽂件)第33讲-Spark核⼼编程:操作RDD实战(transformation和action案例实战)第34讲-Spark核⼼编程:transformation操作开发案例实战第35讲-Spark核⼼编程:action操作开发案例实战第36讲-Spark核⼼编程:RDD持久化详解第37讲-Spark核⼼编程:共享变量(Broadcast Variable和Accumulator)第38讲-Spark核⼼编程:⾼级编程之基于排序机制的wordcount程序第39讲-Spark核⼼编程:⾼级编程之⼆次排序实战第40讲-Spark核⼼编程:⾼级编程之topn与分组取topn实战四、Spark内核源码深度剖析:第41讲-Spark内核源码深度剖析:Spark内核架构深度剖析第42讲-Spark内核源码深度剖析:宽依赖与窄依赖深度剖析第43讲-Spark内核源码深度剖析:基于Yarn的两种提交模式深度剖析第44讲-Spark内核源码深度剖析:SparkContext初始化原理剖析与源码分析第45讲-Spark内核源码深度剖析:Master主备切换机制原理剖析与源码分析第46讲-Spark内核源码深度剖析:Master注册机制原理剖析与源码分析第47讲-Spark内核源码深度剖析:Master状态改变处理机制原理剖析与源码分析第48讲-Spark内核源码深度剖析:Master资源调度算法原理剖析与源码分析第49讲-Spark内核源码深度剖析:Worker原理剖析与源码分析第50讲-Spark内核源码深度剖析:Job触发流程原理剖析与源码分析第51讲-Spark内核源码深度剖析:DAGScheduler原理剖析与源码分析(stage划分算法与task最佳位置算法)第52讲-Spark内核源码深度剖析:TaskScheduler原理剖析与源码分析(task分配算法)第53讲-Spark内核源码深度剖析:Executor原理剖析与源码分析第54讲-Spark内核源码深度剖析:Task原理剖析与源码分析第55讲-Spark内核源码深度剖析:Shuffle原理剖析与源码分析(普通Shuffle与优化后的Shuffle)第56讲-Spark内核源码深度剖析:BlockManager原理剖析与源码分析(Spark底层存储机制)第57讲-Spark内核源码深度剖析:CacheManager原理剖析与源码分析第58讲-Spark内核源码深度剖析:Checkpoint原理剖析与源码分析五、Spark性能优化:第59讲-Spark性能优化:性能优化概览第60讲-Spark性能优化:诊断内存的消耗第61讲-Spark性能优化:⾼性能序列化类库第62讲-Spark性能优化:优化数据结构第63讲-Spark性能优化:对多次使⽤的RDD进⾏持久化或Checkpoint第64讲-Spark性能优化:使⽤序列化的持久化级别第65讲-Spark性能优化:Java虚拟机垃圾回收调优第66讲-Spark性能优化:提⾼并⾏度第67讲-Spark性能优化:⼴播共享数据第68讲-Spark性能优化:数据本地化第69讲-Spark性能优化:reduceByKey和groupByKey第70讲-Spark性能优化:shuffle性能优化六、Spark SQL:第71讲-课程环境搭建:Spark 1.5.1新版本特性、源码编译、集群搭建第72讲-Spark SQL:前世今⽣第73讲-Spark SQL:DataFrame的使⽤第74讲-Spark SQL:使⽤反射⽅式将RDD转换为DataFrame第75讲-Spark SQL:使⽤编程⽅式将RDD转换为DataFrame第76讲-Spark SQL:数据源之通⽤的load和save操作第77讲-Spark SQL:Parquet数据源之使⽤编程⽅式加载数据第78讲-Spark SQL:Parquet数据源之⾃动分区推断第79讲-Spark SQL:Parquet数据源之合并元数据第80讲-Spark SQL:JSON数据源复杂综合案例实战第81讲-Spark SQL:Hive数据源复杂综合案例实战第82讲-Spark SQL:JDBC数据源复杂综合案例实战第83讲-Spark SQL:内置函数以及每⽇uv和销售额统计案例实战第84讲-Spark SQL:开窗函数以及top3销售额统计案例实战第85讲-Spark SQL:UDF⾃定义函数实战第86讲-Spark SQL:UDAF⾃定义聚合函数实战第87讲-Spark SQL:⼯作原理剖析以及性能优化第87讲-Spark SQL:与Spark Core整合之每⽇top3热点搜索词统计案例实战第87讲-Spark SQL:核⼼源码深度剖析(DataFrame lazy特性、Optimizer优化策略等)第87讲-Spark SQL:延伸知识之Hive On Spark七、Spark Streaming:第88讲-Spark Streaming:⼤数据实时计算介绍第89讲-Spark Streaming:DStream以及基本⼯作原理第90讲-Spark Streaming:与Storm的对⽐分析第91讲-Spark Streaming:实时wordcount程序开发第92讲-Spark Streaming:StreamingContext详解第93讲-Spark Streaming:输⼊DStream和Receiver详解第94讲-Spark Streaming:输⼊DStream之基础数据源以及基于HDFS的实时wordcount案例实战第95讲-Spark Streaming:输⼊DStream之Kafka数据源实战(基于Receiver的⽅式)第96讲-Spark Streaming:输⼊DStream之Kafka数据源实战(基于Direct的⽅式)第97讲-Spark Streaming:DStream的transformation操作概览第98讲-Spark Streaming:updateStateByKey以及基于缓存的实时wordcount案例实战第99讲-Spark Streaming:transform以及⼴告计费⽇志实时⿊名单过滤案例实战第100讲-Spark Streaming:window滑动窗⼝以及热点搜索词滑动统计案例实战第101讲-Spark Streaming:DStream的output操作以及foreachRDD性能优化详解第102讲-Spark Streaming:与Spark SQL结合使⽤之top3热门商品实时统计案例实战第103讲-Spark Streaming:缓存与持久化机制详解第104讲-Spark Streaming:Checkpoint机制详解(Driver⾼可靠⽅案详解)第105讲-Spark Streaming:部署、升级和监控实时应⽤程序第106讲-Spark Streaming:容错机制以及事务语义详解第107讲-Spark Streaming:架构原理深度剖析第108讲-Spark Streaming:StreamingContext初始化与Receiver启动原理剖析与源码分析第109讲-Spark Streaming:数据接收原理剖析与源码分析第110讲-Spark Streaming:数据处理原理剖析与源码分析(block与batch关系透彻解析)第111讲-Spark Streaming:性能调优详解第112讲-课程总结(学到了什么?达到了什么⽔平?)Spark开发进阶(升级内容!)⼀、Scala编程进阶:第113讲-Scala编程进阶:Scaladoc的使⽤第114讲-Scala编程进阶:跳出循环语句的3种⽅法第115讲-Scala编程进阶:多维数组、Java数组与Scala数组的隐式转换第116讲-Scala编程进阶:Tuple拉链操作、Java Map与Scala Map的隐式转换第117讲-Scala编程进阶:扩⼤内部类作⽤域的2种⽅法、内部类获取外部类引⽤第118讲-Scala编程进阶:package与import实战详解第119讲-Scala编程进阶:重写field的提前定义、Scala继承层级、对象相等性第120讲-Scala编程进阶:⽂件操作实战详解第121讲-Scala编程进阶:偏函数实战详解第122讲-Scala编程进阶:执⾏外部命令第123讲-Scala编程进阶:正则表达式⽀持第124讲-Scala编程进阶:提取器实战详解第125讲-Scala编程进阶:样例类的提取器实战详解第126讲-Scala编程进阶:只有⼀个参数的提取器第127讲-Scala编程进阶:注解实战详解第128讲-Scala编程进阶:常⽤注解介绍第129讲-Scala编程进阶:XML基础操作实战详解第130讲-Scala编程进阶:XML中嵌⼊scala代码第131讲-Scala编程进阶:XML修改元素实战详解第132讲-Scala编程进阶:XML加载和写⼊外部⽂档第133讲-Scala编程进阶:集合元素操作第134讲-Scala编程进阶:集合的常⽤操作⽅法第135讲-Scala编程进阶:map、flatMap、collect、foreach实战详解第136讲-Scala编程进阶:reduce和fold实战详解⼆、Spark核⼼编程进阶:第137讲-环境搭建-CentOS 6.4虚拟机安装第138讲-环境搭建-Hadoop 2.5伪分布式集群搭建第139讲-环境搭建-Spark 1.5伪分布式集群搭建第140讲-第⼀次课程升级⼤纲介绍以及要点说明第141讲-Spark核⼼编程进阶-Spark集群架构概览第142讲-Spark核⼼编程进阶-Spark集群架构的⼏点特别说明第143讲-Spark核⼼编程进阶-Spark的核⼼术语讲解第144讲-Spark核⼼编程进阶-Spark Standalone集群架构第145讲-Spark核⼼编程进阶-单独启动master和worker脚本详解第146讲-Spark核⼼编程进阶-实验:单独启动master和worker进程以及启动⽇志查看第147讲-Spark核⼼编程进阶-worker节点配置以及spark-evn.sh参数详解第148讲-Spark核⼼编程进阶-实验:local模式提交spark作业第149讲-Spark核⼼编程进阶-实验:standalone client模式提交spark作业第150讲-Spark核⼼编程进阶-实验:standalone cluster模式提交spark作业第151讲-Spark核⼼编程进阶-standalone模式下的多作业资源调度第152讲-Spark核⼼编程进阶-standalone模式下的作业监控与⽇志记录第153讲-Spark核⼼编程进阶-实验:运⾏中作业监控以及⼿⼯打印⽇志第154讲-Spark核⼼编程进阶-yarn-client模式原理讲解第155讲-Spark核⼼编程进阶-yarn-cluster模式原理讲解第156讲-Spark核⼼编程进阶-实验:yarn-client模式提交spark作业第157讲-Spark核⼼编程进阶-yarn模式下⽇志查看详解第158讲-Spark核⼼编程进阶-yarn模式相关参数详解第159讲-Spark核⼼编程进阶-spark⼯程打包以及spark-submit详解第160讲-Spark核⼼编程进阶-spark-submit⽰例以及基础参数讲解第161讲-Spark核⼼编程进阶-实验:spark-submit简单版本提交spark作业第162讲-Spark核⼼编程进阶-实验:spark-submit给main类传递参数第163讲-Spark核⼼编程进阶-spark-submit多个⽰例以及常⽤参数详解第164讲-Spark核⼼编程进阶-SparkConf、spark-submit以及spark-defaults.conf第165讲-Spark核⼼编程进阶-spark-submit配置第三⽅依赖第166讲-Spark核⼼编程进阶-spark算⼦的闭包原理详解第167讲-Spark核⼼编程进阶-实验:对闭包变量进⾏累加操作的⽆效现象第168讲-Spark核⼼编程进阶-实验:在算⼦内打印数据的⽆法看到现象第169讲-Spark核⼼编程进阶-mapPartitions以及学⽣成绩查询案例第170讲-Spark核⼼编程进阶-mapPartitionsWithIndex以开学分班案例第171讲-Spark核⼼编程进阶-sample以及公司年会抽奖案例第172讲-Spark核⼼编程进阶-union以及公司部门合并案例第173讲-Spark核⼼编程进阶-intersection以及公司跨多项⽬⼈员查询案例第174讲-Spark核⼼编程进阶-distinct以及⽹站uv统计案例第175讲-Spark核⼼编程进阶-aggregateByKey以及单词计数案例第176讲-Spark核⼼编程进阶-cartesian以及服装搭配案例第177讲-Spark核⼼编程进阶-coalesce以及公司部门整合案例第178讲-Spark核⼼编程进阶-repartition以及公司新增部门案例第179讲-Spark核⼼编程进阶-takeSampled以及公司年会抽奖案例第180讲-Spark核⼼编程进阶-shuffle操作原理详解第181讲-Spark核⼼编程进阶-shuffle操作过程中进⾏数据排序第182讲-Spark核⼼编程进阶-会触发shuffle操作的算⼦第183讲-Spark核⼼编程进阶-shuffle操作对性能消耗的原理详解第184讲-Spark核⼼编程进阶-shuffle操作所有相关参数详解以及性能调优第185讲-Spark核⼼编程进阶-综合案例1:移动端app访问流量⽇志分析第186讲-Spark核⼼编程进阶-综合案例1:⽇志⽂件格式分析第187讲-Spark核⼼编程进阶-综合案例1:读取⽇志⽂件并创建RDD第188讲-Spark核⼼编程进阶-综合案例1:创建⾃定义的可序列化类第189讲-Spark核⼼编程进阶-综合案例1:将RDD映射为key-value格式第190讲-Spark核⼼编程进阶-综合案例1:基于deviceID进⾏聚合操作第191讲-Spark核⼼编程进阶-综合案例1:⾃定义⼆次排序key类第192讲-Spark核⼼编程进阶-综合案例1:将⼆次排序key映射为RDD的key第193讲-Spark核⼼编程进阶-综合案例1:执⾏⼆次排序以及获取top10数据第194讲-Spark核⼼编程进阶-综合案例1:程序运⾏测试以及代码调试第195讲-Spark核⼼编程进阶-部署第⼆台CentOS机器第196讲-Spark核⼼编程进阶-部署第⼆个Hadoop节点第197讲-Spark核⼼编程进阶-将第⼆个Hadoop节点动态加⼊集群第198讲-Spark核⼼编程进阶-使⽤yarn-client和yarn-cluster提交spark作业三、Spark内核原理进阶:第199讲-Spark内核原理进阶-union算⼦内部实现原理剖析第200讲-Spark内核原理进阶-groupByKey算⼦内部实现原理剖析第201讲-Spark内核原理进阶-reduceByKey算⼦内部实现原理剖析第202讲-Spark内核原理进阶-distinct算⼦内部实现原理剖析第203讲-Spark内核原理进阶-cogroup算⼦内部实现原理剖析第204讲-Spark内核原理进阶-intersection算⼦内部实现原理剖析第205讲-Spark内核原理进阶-join算⼦内部实现原理剖析第206讲-Spark内核原理进阶-sortByKey算⼦内部实现原理剖析第207讲-Spark内核原理进阶-cartesian算⼦内部实现原理剖析第208讲-Spark内核原理进阶-coalesce算⼦内部实现原理剖析第209讲-Spark内核原理进阶-repartition算⼦内部实现原理剖析四、Spark SQL实战开发进阶:第210讲-Spark SQL实战开发进阶-Hive 0.13安装与测试第211讲-Spark SQL实战开发进阶-Thrift JDBC、ODBC Server第212讲-Spark SQL实战开发进阶-CLI命令⾏使⽤第213讲-Spark SQL实战开发进阶-综合案例2:新闻⽹站关键指标离线统计第214讲-Spark SQL实战开发进阶-综合案例2:页⾯pv统计以及排序和企业级项⽬开发流程说明第215讲-Spark SQL实战开发进阶-综合案例2:页⾯uv统计以及排序和count(distinct) bug说明第216讲-Spark SQL实战开发进阶-综合案例2:新⽤户注册⽐例统计第217讲-Spark SQL实战开发进阶-综合案例2:⽤户跳出率统计第218讲-Spark SQL实战开发进阶-综合案例2:版块热度排⾏榜统计第219讲-Spark SQL实战开发进阶-综合案例2:测试与调试五、Spark Streaming实战开发进阶:第220讲-Spark Streaming实战开发进阶-flume安装第221讲-Spark Streaming实战开发进阶-接收flume实时数据流-flume风格的基于push的⽅式第222讲-Spark Streaming实战开发进阶-接收flume实时数据流-⾃定义sink的基于poll的⽅式第223讲-Spark Streaming实战开发进阶-⾼阶技术之⾃定义Receiver第224讲-Spark Streaming实战开发进阶-kafka安装第225讲-Spark Streaming实战开发进阶-综合案例3:新闻⽹站关键指标实时统计第226讲-Spark Streaming实战开发进阶-综合案例3:页⾯pv实时统计第227讲-Spark Streaming实战开发进阶-综合案例3:页⾯uv实时统计第228讲-Spark Streaming实战开发进阶-综合案例3:注册⽤户数实时统计第229讲-Spark Streaming实战开发进阶-综合案例3:⽤户跳出量实时统计第230讲-Spark Streaming实战开发进阶-综合案例3:版块pv实时统计六、Spark运维管理进阶:第231讲-Spark运维管理进阶-基于ZooKeeper实现HA⾼可⽤性以及⾃动主备切换第232讲-Spark运维管理进阶-实验:基于ZooKeeper实现HA⾼可⽤性以及⾃动主备切换第233讲-Spark运维管理进阶-基于⽂件系统实现HA⾼可⽤性以及⼿动主备切换第234讲-Spark运维管理进阶-实验:基于⽂件系统实现HA⾼可⽤性以及⼿动主备切换第235讲-Spark运维管理进阶-作业监控-实验:通过Spark Web UI进⾏作业监控第236讲-Spark运维管理进阶-作业监控-实验:standalone模式下查看历史作业的Web UI第237讲-Spark运维管理进阶-作业监控-实验:启动HistoryServer查看历史作业的Web UI第238讲-Spark运维管理进阶-作业监控-实验:使⽤curl+REST API进⾏作业监控第239讲-Spark运维管理进阶-作业监控-实验:Spark Metrics系统以及⾃定义Metrics Sink第240讲-Spark运维管理进阶-作业资源调度-静态资源分配原理第241讲-Spark运维管理进阶-作业资源调度-动态资源分配原理第242讲-Spark运维管理进阶-作业资源调度-实验:standalone模式下使⽤动态资源分配第243讲-Spark运维管理进阶-作业资源调度-实验:yarn模式下使⽤动态资源分配第244讲-Spark运维管理进阶-作业资源调度-多个job资源调度原理第245讲-Spark运维管理进阶-作业资源调度-Fair Scheduler使⽤详解Spark2.0(升级内容!)七、Spark 2.0深⼊浅出第246讲-Spark 2.0-新特性介绍第247讲-Spark 2.0-新特性介绍-易⽤性:标准化SQL⽀持以及更合理的API第248讲-Spark 2.0-新特性介绍-⾼性能:让Spark作为编译器来运⾏第249讲-Spark 2.0-新特性介绍-智能化:Structured Streaming介绍第250讲-Spark 2.0-新特性介绍-Spark 1.x的Volcano Iterator Model技术缺陷分析第251讲-Spark 2.0-新特性介绍-whole-stage code generation技术和vectorization技术第252讲-Spark 2.0-Spark 2.x与1.x对⽐以及分析、学习建议以及使⽤建议第253讲-Spark 2.0-课程环境搭建:虚拟机、CentOS、Hadoop、Spark等第254讲-Spark 2.0-开发环境搭建:Eclipse+Maven+Scala+Spark第255讲-Spark 2.0-SparkSession、Dataframe、Dataset开发⼊门第256讲-Spark 2.0-Dataset开发详解-初步体验untypd操作案例:计算部门平均年龄与薪资第257讲-Spark 2.0-Dataset开发详解-action操作:collect、count、foreach、reduce等第258讲-Spark 2.0-Dataset开发详解-基础操作:持久化、临时视图、ds与df互转换、写数据等第259讲-Spark 2.0-Dataset开发详解-typed操作:coalesce、repartition第260讲-Spark 2.0-Dataset开发详解-typed操作:distinct、dropDuplicates第261讲-Spark 2.0-Dataset开发详解-typed操作:except、filter、intersect第262讲-Spark 2.0-Dataset开发详解-typed操作:map、flatMap、mapPartitions第263讲-Spark 2.0-Dataset开发详解-typed操作:joinWith第264讲-Spark 2.0-Dataset开发详解-typed操作:sort第265讲-Spark 2.0-Dataset开发详解-typed操作:randomSplit、sample第266讲-Spark 2.0-Dataset开发详解-untyped操作:select、where、groupBy、agg、col、join 第267讲-Spark 2.0-Dataset开发详解-聚合函数:avg、sum、max、min、count、countDistinct 第268讲-Spark 2.0-Dataset开发详解-聚合函数:collect_list、collect_set第269讲-Spark 2.0-Dataset开发详解-其他常⽤函数第270讲-Spark 2.0-Structured Streaming:深⼊浅出的介绍第271讲-Spark 2.0-Structured Streaming:wordcount⼊门案例第272讲-Spark 2.0-Structured Streaming:编程模型第273讲-Spark 2.0-Structured Streaming:创建流式的dataset和dataframe第274讲-Spark 2.0-Structured Streaming:对流式的dataset和dataframe执⾏计算操作第275讲-Spark 2.0-Structured Streaming:output mode、sink以及foreach sink详解第276讲-Spark 2.0-Structured Streaming:管理streaming query第277讲-Spark 2.0-Structured Streaming:基于checkpoint的容错机制第278讲-Spark⾯试、简历中的项⽬编写以及实际⽣产环境的集群和资源配置等课程资源可以在B站搜索。

python的scheduler用法

python的scheduler用法

python的scheduler用法scheduler(调度器)是Python中常用的一个模块,可以用于定时执行任务。

它非常适用于一些需要定时执行的操作,例如定时发送电子邮件、定时备份数据、定时爬取网页等。

本文将详细介绍python 的scheduler用法。

一、安装scheduler模块在开始使用scheduler之前,我们需要先安装该模块。

可以使用pip命令在命令行中进行安装,具体命令如下:pip install scheduler二、引入scheduler模块在编写Python代码时,我们需要引入scheduler模块,以便可以使用该模块提供的功能。

引入scheduler模块的代码如下:```pythonimport scheduler三、创建scheduler对象在使用scheduler模块之前,我们需要先创建一个scheduler对象,以便进行后续的任务调度。

创建scheduler对象的代码如下:```pythons=scheduler.scheduler()四、定义任务函数在使用scheduler进行任务调度时,我们需要定义要执行的任务。

可以通过定义函数的方式来实现。

下面是一个示例:```pythondef task():print("执行任务...")五、添加任务在scheduler对象中,我们可以通过调用`add_job`方法来添加任务。

该方法接受两个参数,第一个参数是要执行的函数名称,第二个参数是触发器类型(可以是日期时间、间隔时间等)。

```pythons.add_job(task,'interval',seconds=10)上述代码表示每隔10秒执行一次task函数。

六、开始调度任务在添加完任务后,我们需要调用scheduler对象的`start`方法来开始执行任务调度。

代码如下:```pythons.start()七、结束调度任务如果我们想要手动结束任务调度,可以调用scheduler对象的`shutdown`方法。

spark工作原理

spark工作原理

spark工作原理Spark是一个快速且通用的大数据处理框架,它使用内存计算来提高数据处理速度。

Spark的工作原理可以分为以下几个关键步骤:1. Driver程序启动:Spark应用程序的入口是Driver程序。

在该程序中,用户指定要执行的任务以及要处理的数据集。

Driver程序将任务分成多个独立的阶段,每个阶段包含多个任务。

2. 任务提交:Driver程序将阶段划分为多个任务,并将它们发送到集群中的各个Executor节点。

每个任务都被分配一个数据分片,即被处理的数据的一个子集。

3. 数据分片:Executor节点会从集群中的存储系统(如Hadoop)中获取分配给它的数据分片。

数据分片可以是Hadoop的HDFS文件系统中的一个块或者其他存储系统中的一部分数据。

4. 任务执行:Executor节点在本地对分配给它的数据分片进行计算。

这些计算通常是对数据进行转换、过滤以及逻辑操作,例如Map、Reduce、Join等。

5. 结果返回:每个任务都会将计算后的结果作为数据分片返回给Driver程序。

这些结果可能是中间结果,也可以是最终结果,具体取决于任务的类型。

6. 数据分片合并:Driver程序接收到所有任务的结果后,会根据需求对结果进行合并。

这个合并过程可能包括Join操作、聚合操作或其他操作,以产生最终的结果。

在Spark内部,有一个称为“弹性分布式数据集”(Resilient Distributed Dataset,简称RDD)的概念。

RDD是Spark的基本抽象,是一种可并行操作的分布式数据集,具有容错性。

RDD可以重新计算或者恢复丢失的分片数据。

这种容错性使得Spark能够处理大规模数据集时能够保证数据处理的正确性和可靠性。

总的来说,Spark的工作原理是通过将任务分解为多个阶段和任务,使用分布式计算的方式对数据进行处理。

通过内存计算和容错机制,Spark能够实现快速和可靠的大规模数据处理。

python的scheduler用法 -回复

python的scheduler用法 -回复

python的scheduler用法-回复Python中的scheduler用于定时执行任务,它是一个非常强大的工具,可以帮助我们实现定时执行代码的功能。

本文将介绍scheduler的用法,并逐步回答关于该主题的问题。

在Python中,scheduler是通过第三方库APScheduler来实现的。

APScheduler是一个简单易用的Python定时任务处理库,它支持多个调度器,包括异步的、非阻塞的和基于线程的调度器。

它允许我们以各种方式设置任务的调度时间,并提供了灵活的选项来处理任务的执行。

首先,我们需要安装APScheduler库。

可以使用pip命令在命令行中安装,如下所示:pip install apscheduler安装完成后,我们可以在Python脚本中导入APScheduler库:pythonfrom apscheduler.schedulers.blocking import BlockingScheduler接下来,我们就可以创建一个scheduler对象:pythonscheduler = BlockingScheduler()我们可以使用scheduler对象的`add_job()`方法来添加一个任务。

下面是一个示例:pythondef my_job():print("This is a scheduled task.")scheduler.add_job(my_job, 'cron', second='0,30')在这个示例中,我们定义了一个名为`my_job`的函数,并将其添加到scheduler中。

`add_job()`方法的第一个参数是要执行的函数或方法名称。

第二个参数是一个字符串,用于指定调度器的类型。

在这个例子中,我们使用了'cron'类型。

最后,我们可以通过提供一些关键字参数来设置任务的调度时间。

Spark作业执行流程源码解析

Spark作业执行流程源码解析

Spark作业执⾏流程源码解析本⽂梳理⼀下Spark作业执⾏的流程。

⽬录Spark作业和任务调度系统是其核⼼,通过内部RDD的依赖DAG,使得模块之间的调⽤和处理变得游刃有余。

相关概念Job(作业):通过⾏动操作⽣成的⼀个或多个调度阶段Stage:根据依赖关系划分的多个任务集,称为调度阶段,也叫做TaskSet(任务集)。

划分Stage是由DAGScheduler进⾏的,任务阶段分为Shuffle Map Stage和Result Stage。

Task:是Spark执⾏计算的最⼩单位,会被分发到Executor中执⾏。

DAGScheduler:是⾯向调度阶段的任务调度器,接收Spark应⽤提交的作业,根据依赖关系划分stage,并提交给TaskScheduler。

TaskScheduler:是⾯向任务的调度器,接收DAGScheduler划分好的stage,发送给Worker节点的Executor运⾏任务。

关于RDD相关知识、⾏动操作、宽窄依赖请参考概述Spark作业主要是根据我们编写的业务处理代码,⽣成⼀系列相互依赖的调度阶段,之后将调度阶段中的任务提交Executor的执⾏的过程。

上图是spark作业运⾏流程图。

主要分为四块:构建DAG⾏动操作触发提交作业,提交之后根据依赖关系构造DAG。

划分调度阶段、提交调度阶段DAGScheduler中根据宽依赖划分调度阶段(stage)。

每个stage包含多个task,组成taskset提交给TaskScheduler执⾏通过集群管理器启动任务TaskScheduler收到DAGScheduler提交的任务集,以任务的形式⼀个个分发到Executor中进⾏执⾏。

Executor端执⾏任务,完成后存储报告结果Executor接到任务后,扔到线程池中执⾏任务。

任务完成后,报告结果给Driver。

源码解析从以下的代码展开叙述:def main(args: Array[String]): Unit = {val sc = new SparkContext("local", "word-count", new SparkConf())val words = Seq("hello spark", "hello scala", "hello java")val rdd = sc.makeRDD(words)rdd.flatMap(_.split(" ")).map((_, 1)).reduceByKey(_ + _).sortByKey().foreach(println(_))}这是⼀个简单的WordCount案例。

Spark Streaming源码解读之Job详解

Spark Streaming源码解读之Job详解

Spark Streaming源码解读之Job详解一:Spark Streaming Job生成深度思考1. 做大数据例如Hadoop,Spark等,如果不是流处理的话,一般会有定时任务。

例如10分钟触发一次,1个小时触发一次,这就是做流处理的感觉,一切不是流处理,或者与流处理无关的数据都将是没有价值的数据,以前做批处理的时候其实也是隐形的在做流处理。

2. JobGenerator构造的时候有一个核心的参数是jobScheduler, jobScheduler是整个作业的生成和提交给集群的核心,JobGenerator会基于DStream生成Job。

这里面的Job就相当于Java中线程要处理的Runnable里面的业务逻辑封装。

Spark的Job就是运行的一个作业。

3. Spark Streaming除了基于定时操作以外参数Job,还可以通过各种聚合操作,或者基于状态的操作。

4. 每5秒钟JobGenerator都会产生Job,此时的Job是逻辑级别的,也就是说有这个Job,并且说这个Job具体该怎么去做,此时并没有执行。

具体执行的话是交给底层的RDD的action去触发,此时的action也是逻辑级别的。

底层物理级别的,Spark Streaming他是基于DStream构建的依赖关系导致的Job是逻辑级别的,底层是基于RDD的逻辑级别的。

val ssc = new StreamingContext(conf, Seconds(5))115. Spark Streaming的触发器是以时间为单位的,storm是以事件为触发器,也就是基于一个又一个record. Spark Streaming基于时间,这个时间是Batch Duractions从逻辑级别翻译成物理级别,最后一个操作肯定是RDD的action,但是并不想一翻译立马就触发job。

这个时候怎么办?6. action触发作业,这个时候作为Runnable接口封装,他会定义一个方法,这个方法里面是基于DStream的依赖关系生成的RDD。

spark作业运行流程

spark作业运行流程

spark作业运行流程
Spark作业运行流程简述如下:
1. 创建SparkContext:在应用中初始化Spark环境,连接到集群资源管理器(如Standalone、YARN或Mesos)。

2. 提交作业:通过spark-submit命令提交打包好的应用程序给Master节点。

3. 申请资源:SparkContext向资源管理器请求Executor资源,资源管理器分配资源并在Worker节点上启动Executor进程。

4. DAG构建与优化:根据用户代码生成DAG(有向无环图),表示任务的执行计划。

DAGScheduler将DAG划分为Stage(阶段),每个Stage包含多个可以并行执行的Task。

5. 任务调度:DAGScheduler将TaskSet提交给TaskScheduler,后者负责在Executor之间调度和分配任务。

6. 执行任务:Executor执行任务,任务可能涉及数据加载、转换操作和行动操作,结果写回存储系统或输出到控制台。

7. 反馈与容错:Driver监控所有任务的执行状态,并处理失败任务的重试,确保作业最终成功完成。

Spark任务调度流程及调度策略分析

Spark任务调度流程及调度策略分析

Spark任务调度流程及调度策略分析Spark任务调度TaskScheduler调度⼊⼝:(1)CoarseGrainedSchedulerBackend 在启动时会创建DriverEndPoint. ⽽DriverEndPoint中存在⼀定时任务,每隔⼀定时间(spark.scheduler.revive.interval, 默认为1s)进⾏⼀次调度(给⾃⾝发送ReviveOffers消息,进⾏调⽤makeOffers进⾏调度)。

代码如下所⽰override def onStart() {// Periodically revive offers to allow delay scheduling to workval reviveIntervalMs = conf.getTimeAsMs("spark.scheduler.revive.interval", "1s")reviveThread.scheduleAtFixedRate(new Runnable {override def run(): Unit = Utils.tryLogNonFatalError {Option(self).foreach(_.send(ReviveOffers))}}, 0, reviveIntervalMs, LISECONDS)}(2)当Executor执⾏完成已分配任务时,会向Driver发送StatusUpdate消息,当Driver接收到消息后会调⽤ makeOffers(executorId)⽅法,进⾏任务调度, CoarseGrainedExecutorBackend 状态变化时向Driver (DriverEndPoint)发送StatusUpdate消息override def statusUpdate(taskId: Long, state: TaskState, data: ByteBuffer) {val msg = StatusUpdate(executorId, taskId, state, data)driver match {case Some(driverRef) => driverRef.send(msg)case None => logWarning(s"Drop $msg because has not yet connected to driver")}}Dirver接收到StatusUpdate消息时将会触发设调度(makeOffers),为完成任务的Executor分配任务。

Spark任务执行的流程

Spark任务执行的流程

Spark任务执⾏的流程Spark 任务执⾏的流程四个步骤1.构建DAG(调⽤RDD上的⽅法)2.DAGScheduler将DAG切分Stage(切分的依据是Shuffle),将Stage中⽣成的Task以TaskSet的形式给TaskScheduler3.TaskScheduler调度Task(根据资源情况将Task调度到相应的Executor中)4.Executor接收Task,然后将Task丢⼊到线程池中执⾏DAG 有向⽆环图(数据执⾏过程,有⽅法,⽆闭环)DAG描述多个RDD的转换过程,任务执⾏时,可以按照DAG的描述,执⾏真正的计算(数据被操作的⼀个过程)DAG是有边界的:开始(通过SparkContext创建的RDD),结束(触发Action,调⽤run Job就是⼀个完整的DAG就形成了,⼀旦触发Action就形成了⼀个完整的DAG)⼀个RDD只是描述了数据计算过程中的⼀个环节,⽽DGA由⼀到多个RDD组成,描述了数据计算过程中的所有环节(过程)⼀个Spark Application中是有多少个DAG:⼀到多个(取决于触发了多少次Action)--------------------------------------------⼀个DAG中可能有产⽣多种不同类型和功能的Task,会有不同的阶段DAGScheduler:将⼀个DAG切分成⼀到多个Stage,DAGScheduler切分的依据是Shuffle(宽依赖)为什么要切分Stage?⼀个复杂的业务逻辑(将多台机器上具有相同属性的数据聚合到⼀台机器上:shuffle)如果有shuffle,那么就意味着前⾯阶段产⽣的结果后,才能执⾏下⼀个阶段,下⼀个阶段的计算要依赖上⼀个阶段的数据。

在同⼀个Stage中,会有多个算⼦,可以合并在⼀起,我们称其为pipeline(流⽔线:严格按照流程、顺序执⾏)--------------------------------------------宽依赖和窄依赖⼀般来说普通的join都是宽依赖rdd的特殊jionstage过程,3个stage 6 个Task ⼀个stage有两个分区就有两个Task,⼀个Application有很多job,job划分依据run job⾏动算⼦,调⽤了⼏次就有⼏个job ,stage划分是依据suffle来的,相同的过程划分到同⼀个stage,产⽣shuffle的阶段⼀份为⼆。

Spark两种运行流程

Spark两种运行流程

Spark两种运⾏流程SparkOnYarn(cluster)1.由客户端向ResourceManager提交请求,上传jar包和配置参数到RM分配的HDFS路径2.ResuurceManager向NodeManager申请资源,创建Spark ApplicationMaster(每⼀个SparkContext都有⼀个appmaster)3.NM启动ApplicationMaster,并向RMMaster注册4.ApplicationMaster找到HDFS中的⽂件,启动SparkContext、DAGScheduler和和YARN Cluster Scheduler5.RS向RSM注册申请container(comtainer有两种,⼀种是RS向RSM申请,运⾏在appmaster中,可唯⼀指定applicationMaster所需资源,另⼀种是applicationMaster向RM申请,由RM资源调度器异步分配给appmaster,运⾏在各个任务上)6.RM通知NM分配Container(每个Container对应⼀个executor)7.Spark ApplicationMaster直接和Container(executor)进⾏交互,完成分布式任务8.程序运⾏完后applicationMaster向RM注销⾃⼰cluster模式下driver运⾏在集群中,其实是在ApplicationMaster这个进程中SparkStandalone1.Spark-submit提交任务,调⽤spark-submit.sh,启动spark-class,SparkSubmit的main⽅法被启动,然后反射启动程序main⽅法,创建SparkContext,SparkContext创建完成后会创建出SparkEnv,DAGscheduler,TaskScheduler,StandaloneSchedulerBackend2.StandaloneSchedulerBackend调⽤StandaloneAppClient创建出来ClientEndPoint,调⽤⽗类的start⽅法创建DriverEndPoint3.ClientEndPoint向master注册application,并封装启动executor的命令4.master收到来⾃client端的app注册请求后,回去遍历⾃⼰的worker列表,找出有空闲资源的worker,然后为ec分配资源,通知worker启动executor5.响应driver注册成功6.worker根据指令启动ec,ec会向driverEndpoint注册并保持通信,driverEndpoint返回注册成功的消息,然后会创建出线程池,等待task提交过来运⾏。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

Spark源码学习(4)——Scheduler Scheduler的基本过程用户提交的Job到DAGScheduler后,会封装成ActiveJob,同时启动JobWaiter监听作业的完成情况。

同时依据job中RDD的dependency和dependency属性(窄依赖NarrowDependency,宽依赖ShufflerDependecy),DAGScheduler会根据依赖关系的先后产生出不同的stage DAG(result stage, shuffle map stage)。

在每一个stage内部,根据stage产生出相应的task,包括ResultTask或是ShuffleMapTask,这些task会根据RDD中partition的数量和分布,产生出一组相应的task,并将其包装为TaskSet提交到TaskScheduler上去。

DAGSchedulerDAGScheduler是高层级别的调度器。

实现了stage-oriented调度。

它计算一个DAG中stage 的工作。

并将这些stage输出落地物化。

最终提交stage以taskSet方式提交给TaskScheduler。

DAGScheduler需要接收上下层的消息,它也是一个actor。

这里主要看看他的一些事件处理。

以下是的所处理的事件。

private[scheduler] case class JobSubmitted(jobId: Int,finalRDD: RDD[_],func: (TaskContext, Iterator[_]) => _,partitions: Array[Int],callSite: CallSite,listener: JobListener,properties: Properties = null)extends DAGSchedulerEventprivate[scheduler] case class StageCancelled(stageId: Int) extends DAGSchedulerEventprivate[scheduler] case class JobCancelled(jobId: Int) extends DAGSchedulerEventprivate[scheduler] case class JobGroupCancelled(groupId: String) extends DAGSchedulerEventprivate[scheduler] case object AllJobsCancelled extends DAGSchedulerEventprivate[scheduler]case class BeginEvent(task: Task[_], taskInfo: TaskInfo) extends DAGSchedulerEventprivate[scheduler]case class GettingResultEvent(taskInfo: TaskInfo) extends DAGSchedulerEvent还有很多,不一一罗列。

JobSubmitted//处理提交的作业,完成Job到stage的转换,生成finalStage,并SubmitStage。

private[scheduler] def handleJobSubmitted(jobId: Int,finalRDD: RDD[_],func: (TaskContext, Iterator[_]) => _,partitions: Array[Int],callSite: CallSite,listener: JobListener,properties: Properties) {var finalStage: ResultStage = nulltry {// New stage creation may throw an exception if, for example, jobs are run on a// HadoopRDD whose underlying HDFS files have been deleted.finalStage = newResultStage(finalRDD, func, partitions, jobId, callSite)} catch {case e: Exception =>logWarning("Creating new stage failed due to exception - job: " + jobId, e)listener.jobFailed(e)return}val job = new ActiveJob(jobId, finalStage, callSite, listener, properties)clearCacheLocs()logInfo("Got job %s (%s) with %d output partitions".format(job.jobId, callSite.shortForm, partitions.length))logInfo("Final stage: " + finalStage + " (" + + ")")logInfo("Parents of final stage: " + finalStage.parents)logInfo("Missing parents: " + getMissingParentStages(finalStage))val jobSubmissionTime = clock.getTimeMillis()jobIdToActiveJob(jobId) = jobactiveJobs += jobfinalStage.setActiveJob(job)val stageIds = jobIdToStageIds(jobId).toArrayval stageInfos = stageIds.flatMap(id => stageIdToStage.get(id).map(_.latestInfo))listenerBus.post(SparkListenerJobStart(job.jobId, jobSubmissionTime, stageInfos, properties))submitStage(finalStage)}进入submitStage方法。

submitStage提交stage,第一个提交的是没有父依赖关系的。

/** Submits stage, but first recursively submits any missing parents. */private def submitStage(stage: Stage) {val jobId = activeJobForStage(stage)if (jobId.isDefined) {logDebug("submitStage(" + stage + ")")if (!waitingStages(stage) && !runningStages(stage) && !failedStages(stage)) {val missing = getMissingParentStages(stage).sortBy(_.id)logDebug("missing: " + missing)if (missing.isEmpty) {logInfo("Submitting " + stage + " (" + stage.rdd + "), which has no missing parents")//没有stage依赖submitMissingTasks(stage, jobId.get)} else {//有父依赖递归处理父stagefor (parent <- missing) {submitStage(parent)}waitingStages += stage}}} else {abortStage(stage, "No active job for stage " + stage.id, None)}}如果计算中发现当前的stage没有任何的依赖关系。

则直接提交task。

源码中的getMissingParentStages是获取父stage。

源码如下://查找所有的stage封装成list集合private def getMissingParentStages(stage: Stage): List[Stage] = {val missing = new HashSet[Stage]val visited = new HashSet[RDD[_]]// We are manually maintaining a stack here to prevent StackOverflowError// caused by recursively visitingval waitingForVisit = new Stack[RDD[_]]def visit(rdd: RDD[_]) {if (!visited(rdd)) {visited += rddval rddHasUncachedPartitions = getCacheLocs(rdd).contains(Nil)if (rddHasUncachedPartitions) {for (dep <- rdd.dependencies) {dep match {//如果是ShufflerDependecy,则新建一个ShuffleMapStage,且该stage是可用的话,则加入missing中//ShufflerDependecy表示Shuffle过程的依赖case shufDep: ShuffleDependency[_, _, _] =>val mapStage = getShuffleMapStage(shufDep, stage.firstJobId)if (!mapStage.isAvailable) {missing += mapStage}case narrowDep: NarrowDependency[_] =>waitingForVisit.push(narrowDep.rdd)}}}}}waitingForVisit.push(stage.rdd)while (waitingForVisit.nonEmpty) {visit(waitingForVisit.pop())}missing.toList}继续submitStage,进入submitMissingTasks方法。

相关文档
最新文档