spark1.3版本源码解读
来源:互联网 发布:一个算法的时间复杂度 编辑:程序博客网 时间:2024/06/05 23:54
脚本启动流程
1、在主节点启动start-all.sh 调用 start-master.sh 调用 start-daemon.sh org.apache.spark.deploy.master.Master 调用 spark-class (启动后面类的main方法)2、start-slaves.sh 调用 start-slave.sh spark://hadoop01:70773、spark-deamon.sh 调用 spark-class 类名 调用org.apache.spark.launcher.Main
sparksubmit 关键源码
def main(args: Array[String]): Unit = { //将传入的参数封装为sparksubmitArguments对象 val appArgs = new SparkSubmitArguments(args) if (appArgs.verbose) { printStream.println(appArgs) } //传入的事件类型 一般是submit appArgs.action match { case SparkSubmitAction.SUBMIT => submit(appArgs) case SparkSubmitAction.KILL => kill(appArgs) case SparkSubmitAction.REQUEST_STATUS => requestStatus(appArgs) }}submit方法中,先解析参数 val (childArgs, childClasspath, sysProps, childMainClass) = prepareSubmitEnvironment(args)再执行dorunmain方法里面主要是执行 runMain(childArgs, childClasspath, sysProps, childMainClass, args.verbose)在runmain方法中先通过反射拿到目标类 mainClass = Class.forName(childMainClass, true, loader)拿到main方法 val mainMethod = mainClass.getMethod("main", new Array[String](0).getClass)调用main方法 mainMethod.invoke(null, childArgs.toArray)然后main方法中我们生成了 sparkconf 和sparkcontext
sparkcontext 任务的人口类
主要做件事1、创建SparkEnv(内部启动Actor)2、3、4、创建任务调度器TaskScheduler5、6、7、创建DAGScheduler 切分Stage的8、启动TaskScheduler
实现调用了creatSparkEnv 创建SparkEnv //TODO 该方法创建SparkEnv private[spark] def createSparkEnv( conf: SparkConf, isLocal: Boolean, listenerBus: LiveListenerBus): SparkEnv = { //通过调用SparkEnv里的静态方法来创建SparkEnv SparkEnv.createDriverEnv(conf, isLocal, listenerBus) } private[spark] val env = createSparkEnv(conf, isLocal, listenerBus)通过SparkEnv.createDriverEnv(conf, isLocal, listenerBus)调用的是里面的creat方法在creat方法中有 AkkaUtils.createActorSystem(actorSystemName, hostname, port, conf, securityManager)也就是在creat方法中通过AkkaUtils来创建ActorSystem //TODO 创建一个TaskScheduler private[spark] var (schedulerBackend, taskScheduler) = SparkContext.createTaskScheduler(this, master)在任务调度器中有多种启动模式,跟据传入的sparkurl来匹配模式 //TODO spark的StandAlone模式 case SPARK_REGEX(sparkUrl) => //TODO 创建了一个TaskSchedulerImpl val scheduler = new TaskSchedulerImpl(sc) val masterUrls = sparkUrl.split(",").map("spark://" + _) //TODO 创建了一个SparkDeploySchedulerBackend 后端调度器 val backend = new SparkDeploySchedulerBackend(scheduler, sc, masterUrls) //TODO 调用initialize创建调度器 scheduler.initialize(backend) (backend, scheduler)
降龙18掌
打包上传任务 /spark-submit --class com.sam...xxx --master spark://node01:7077 /root/x.jar ....Spark任务分配有两种方式-尽量打散(默认),尽量集中1、调用SparkSubmit类,内部执行submit-->doRunMain-->通过反射拿到程序的主类对象-->执行主类的main方法2、SparkContext 构建Sparkconf与SparkContext对象,在Sparkcontext类中主要做了3件事, 1、创建SparkEnv对象(创建了ActorSystem对象(创建Actor)) 2、Taskscheduler(用来生成并发送task给Executor) 3、DAGScheduler(用来化分stage)3、clientActor(driver端创建)将任务信息封装到ApplicationDescription对象,并且提交给Master4、Master收到clientActor提交的任务信息后,把任务信息存到内存中,然后又将任务信息放到队列中(waitingApps)5、当开始执行这个任务信息时,调用scheduler方法,进行资源调度6、将调度好的资源封装到LaunchExecutor,并发送给对应的worker7、worker接收到Master发送的调度信息(LaunchExecutor)后,将信息封装成一个ExecutorRunner对象8、封装成ExecutorRunner后,调用它的start方法,开始启动CoarseGrainedExecutorBackend对象,9、Executor启动后开始向DriverActor进行反向注册10、与DriverActor注册成功后,创建一个线程池(ThreadPool),用来执行任务11、当所有的Executor注册完成后,作业环境也就准备好了,Driver端会结束与SparkContext对象的初始化(也就是初始化已完成)12、当driver初始化完成后(创建了一个sc实例),会继续执行我们提交的App代码,当触发一个Action的RDD算子时,就会触发一个job,这时就会调用DAGScheduler对象进行Stage划分13、DAGScheduler 开始进行Stage划分,拿到最后的RDD,从后往前找,调用newstage方法,14、将划分好的stage按照分区生成一个个的Task,并且封装到TaskSet对象,然后TaskSet提交到TaskScheduler。15、TaskScheduler 接收到提交的TaskSet,拿到一个序列化器,将Taskset反序列化,将反序列化好的Taskset封装到LaunchExecutor并提交到DriverActor16、把LaunchExecutor发送到Executor上 通过广播变量17、Executor接收到DriverActor发送过来的任务(LaunchExecutor),会将其封装成TaskRunner,然后从线程池中获取线程来执行TaskRunner18、TaskRunner拿到反序列化器,反序列化Taskset,然后执行App代码,也就是对RDD分区上执行的算子和自定义函数
阅读全文
0 0
- spark1.3版本源码解读
- 1.7版本 Arraylist源码解读
- 编译spark1.6.1源码
- Spark1.6源码编译
- Spark1.6.2 源码编译
- spark1.2源码编译
- Spark通信机制:1)Spark1.3 vs Spark1.6源码分析
- prototype.js 源码解读v1.3.1版本
- prototype.js源码解读v1.3.1版本
- prototype.js 源码解读v1.3.1版本
- vue源码解读-各构建版本
- CppUnit源码解读(3)
- CppUnit源码解读(3)
- CYYMysql 源码解读 3
- spark1.2.0源码MLlib --- SVD
- spark源码解读3之RDD中top源码解读
- zxing项目源码解读(2.3.0版本,Android部分)
- mybatis源码解读(3)
- SpringBoot连接数据库JDBCTemplate方式
- PAT 1006 换个格式输出整数
- 深入理解java抽象与接口
- JDBC使用
- 仿京东分类列表MVP模式请求
- spark1.3版本源码解读
- Python基础-匿名函数 Lambda
- PAT-1015.反转链表(25)
- LeetCode 268.Missing Number
- 获取手机号归属地的3种方法
- 深度强化学习——DQN
- 如何配置linux的IP地址
- JAVA通过Gearman实现MySQL到Redis的数据同步(异步复制)
- hello,C语言