SparkWordCount源码原理

来源:互联网 发布:深圳云计算招聘岗位 编辑:程序博客网 时间:2024/06/07 00:46
def textFile(      path: String,      minPartitions: Int = defaultMinPartitions): RDD[String] = withScope {    assertNotStopped()    hadoopFile(path, classOf[TextInputFormat], classOf[LongWritable], classOf[Text],      minPartitions).map(pair => pair._2.toString).setName(path) //这里由于偏移量没用所以用_2  }  这是一个从左hdfs 向右的过程  hdfs              sc.textFile  (带偏移量)         map 结果(去掉偏移量)生成了一个RDD                HadoopRDD(LongWriteable,Text)       MapPartitionsRDD[String]  hello lilei       (0,"hello lilei")               “hello lilei”  hello lucy        (1,"hello lucy")                "hello lucy"  上面右接下面左  flatMap(_.split(" "))             map((_,1))                  reduceByKey(_+_)  MapPartitionsRDD[String]      MapPartitionsRDD[String,Int]    ShuffledRDD[String,Int,Int]  "hello,lilei,hello,lucy"  ("hello",1),("lilei",1)....     两个过程,分区聚合,全局聚合,中间是shuffle过程,洗牌,分区中 这里会宽依赖  上面右接下面左  saveAsTextFile("hdfs://...")  MapPartitionsRDD[String,Int]  初始设置分区,或者文件分区时,保存默认也是这些分区  整个过程创建了6个RDD
//hdoopFile 返回一个RDD def hadoopFile[K, V](      path: String,      inputFormatClass: Class[_ <: InputFormat[K, V]],      keyClass: Class[K],      valueClass: Class[V],      minPartitions: Int = defaultMinPartitions): RDD[(K, V)] = withScope {    assertNotStopped()    // A Hadoop configuration can be about 10 KB, which is pretty big, so broadcast it.    val confBroadcast = broadcast(new SerializableConfiguration(hadoopConfiguration))    val setInputPathsFunc = (jobConf: JobConf) => FileInputFormat.setInputPaths(jobConf, path)    new HadoopRDD(      this,      confBroadcast,      Some(setInputPathsFunc),      inputFormatClass,      keyClass,      valueClass,      minPartitions).setName(path)  }

一个项目源码执行流程(主要是sparksubmit与sparkContext)

1、SparkSubmit  执行runmain()方法 根据传入的类名找到jar中的类,执行main方法2、执行项目(以WC为例),执行WC的main 方法3、WC的main方法中 一开始是 new 了一个SparkConf 与SparkContext4、SparkContext 通过createSparkEnv() 调用SparkEnv的createDriverEnv()5、在SparkEnv中SparkEnv的createDriverEnv()调用create方法    create方法中调用AkkaUtils6、在AkkaUtils里通过createActorSystem来创建Actor7、SparkContext 通过creatTaskScheduler 来new 一个TaskSchedulerImpl(任务调度器)和SparkDeploySchedulerBackend(后端调度器)8、SparkContext 通过new来创建了DAGScheduler(划分stage的)

TaskScheduler 的流程

启动TaskScheduler 是 TaskScheduler 的start方法在Start方法中:先启动后端调度器 也就是SparkDeploySchedulerBackend (后端调度器的一个实现方法),在SparkDeploySchedulerBackend的start方法中,调用父类的start方法(super.start())。父类的start方法中创建了driveractor。然后在SparkDeploySchedulerBackend的start方法中,  创建了Command(准备了执行任务线程的类名)ApplicationDescription(封装了Excutor需要用的参数,像占用内存大小,核数),接下来创建了一个Appclient的实例将配置信息(包括appdesc)传进去。然后调用clien.start()。在client 中创建了client的Actor。在后端调度器这,一共创建了2个Actor,driverActor(与excutor通信),clientActor(与master通信)后端调度器是在driver端启动。也就是driver端启动的driverActor和clientActor通过sparkenv调用scheduler

client端与master端通信

1、在prestart方法中 主要是registerWithMaster,向master注册,这里有高可用集群,它会遍历所有master的url,然后与活跃的master发连接2、master 端接收到client的注册消息,将client的信息加入到hashset(去重)与ArrayBuffer中(也就是存两份),还要信息持久化。然后master向client发送响应消息(携带appid,和masterurl)。开始任务调度3client 接收到master返回的注册响应消息,先改masterurl,再启动一个监听器,连接appid

接上面2后的任务调度(注册成功,master返回消息后 master启动)

只要新的计算资源加进来时都会发生资源调度。两种调度方式  spreadOutApps (尽量打散,默认) (尽量集中)spreadOutApps : 1、从waitingApps(client保存的Arraybuffer)过滤取出合适的apps(活跃,内存是否足够,空闲的cpu核数),用来启动executor2、尽量打散,把任务用循环的方式调度到尽量多的节点上。(尽量集中,意思是一个节点有多少核数,有限分配多少。尽量少节点)3、在节点(worker)上启动executor   launchExecutor

work启动executor

先在master中1、将executor的描述信息加入workerinfo中2、master向worker发送消息,告诉worker启动executor3、同时向client发送消息,告诉client executor已经启动再 worker中接收到master的启动executor的消息。1、worker接收到master消息,2、内部创建一个空间,new 一个 executorrunner再的同时 client接收到master的消息  (executor已经启动)1client接收到后,监听executor的注册

CoarseGrainedExecutorBackend 中启动的executor进程的类

在main方法中,主要是封装参数,与执行run方法在run方法中:创建Actorsystem对象  创建actor在生命周期方法中prestart: 向driver发送注册消息  ,接收在CoarseGrainedSchedulerBackend 中,在CoarseGrainedSchedulerBackend中接收到上面发送的消息后,执行makeoffers方法(就是为提交任务做准备)

RDD的生成

先从一个action的算子看起,向saveasfile1、拿到一个输出流(writer),2、调用sparkcontext的 runjob方法 传入 writertoFile的函数3、调用dagscheduler 的runjob方法,进行stage的切分。4、调用submitjob,开始提交作业5、submitjob中,首先得到分区数 , 调用eventprocessLoop(任务处理器,循环取出数据)6、在dagscheduler中切分stage
原创粉丝点击