一、以Wordcount为例来分析

1、Wordcount

val lines = sc.textFile()
val words = lines.flatMap(line => line.split(" "))
val pairs = words.map(word => (word, 1))
val counts = pairs.reduceByKey(_ + _)
counts.foreach(count => println(count._1 + ": " + count._2))

2、源码分析

###org.apache.spark/SparkContext.scala
###textFile() /**
* 首先,hadoopFile()方法的调用,会创建一个HadoopRDD,其中的元素,其实是(key,value)pais
* key是hdfs或文本文件的每一行的offset,value是文本行
* 然后对HadoopRDD调用map()方法,会剔除key,只保留value,然后会获得一个MapPartitionRDD
* MapPartitionRDD内部的元素,其实就是一行一行的文本行
* @param path
* @param minPartitions
* @return
*/
def textFile(path: String, minPartitions: Int = defaultMinPartitions): RDD[String] = {
assertNotStopped()
hadoopFile(path, classOf[TextInputFormat], classOf[LongWritable], classOf[Text],
minPartitions).map( pair => pair._2.toString).setName(path)
} ###org.apache.spark.rdd/RDD.scala def flatMap[U: ClassTag](f: T => TraversableOnce[U]): RDD[U] = {
val cleanF = sc.clean(f)
new MapPartitionsRDD[U, T](this, (context, pid, iter) => iter.flatMap(cleanF))
} def map[U: ClassTag](f: T => U): RDD[U] = {
val cleanF = sc.clean(f)
new MapPartitionsRDD[U, T](this, (context, pid, iter) => iter.map(cleanF))
} 其实RDD里是没有reduceByKey的,因此对RDD调用reduceByKey()方法的时候,会触发scala的隐式转换;此时就会在作用域内,寻找隐式转换,
会在RDD中找到rddToPairRDDFunctions()隐式转换,然后将RDD转换为PairRDDFunctions。 implicit def rddToPairRDDFunctions[K, V](rdd: RDD[(K, V)])
(implicit kt: ClassTag[K], vt: ClassTag[V], ord: Ordering[K] = null): PairRDDFunctions[K, V] = {
new PairRDDFunctions(rdd)
} 接着会调用PairRDDFunctions中的reduceByKey()方法; def reduceByKey(partitioner: Partitioner, func: (V, V) => V): RDD[(K, V)] = {
combineByKey[V]((v: V) => v, func, func, partitioner)
} ###org.apache.spark.rdd/RDD.scala def foreach(f: T => Unit) {
val cleanF = sc.clean(f)
sc.runJob(this, (iter: Iterator[T]) => iter.foreach(cleanF))
} foreach调用了runJob方法,一步步追踪runJob方法,首先调用SparkContext的runJob: def runJob[T, U: ClassTag](rdd: RDD[T], func: Iterator[T] => U): Array[U] = {
runJob(rdd, func, 0 until rdd.partitions.size, false)
} … 最后:
def runJob[T, U: ClassTag](
rdd: RDD[T],
func: (TaskContext, Iterator[T]) => U,
partitions: Seq[Int],
allowLocal: Boolean,
resultHandler: (Int, U) => Unit) {
if (stopped) {
throw new IllegalStateException("SparkContext has been shutdown")
}
val callSite = getCallSite
val cleanedFunc = clean(func)
logInfo("Starting job: " + callSite.shortForm)
if (conf.getBoolean("spark.logLineage", false)) {
logInfo("RDD's recursive dependencies:\n" + rdd.toDebugString)
}
// 调用SparkContext,之前初始化时创建的dagScheduler的runJob()方法
dagScheduler.runJob(rdd, cleanedFunc, partitions, callSite, allowLocal,
resultHandler, localProperties.get)
progressBar.foreach(_.finishAll())
rdd.doCheckpoint()
}

16、job触发流程原理剖析与源码分析的更多相关文章

  1. 65、Spark Streaming:数据接收原理剖析与源码分析

    一.数据接收原理 二.源码分析 入口包org.apache.spark.streaming.receiver下ReceiverSupervisorImpl类的onStart()方法 ### overr ...

  2. 66、Spark Streaming:数据处理原理剖析与源码分析(block与batch关系透彻解析)

    一.数据处理原理剖析 每隔我们设置的batch interval 的time,就去找ReceiverTracker,将其中的,从上次划分batch的时间,到目前为止的这个batch interval ...

  3. 18、TaskScheduler原理剖析与源码分析

    一.源码分析 ###入口 ###org.apache.spark.scheduler/DAGScheduler.scala // 最后,针对stage的task,创建TaskSet对象,调用taskS ...

  4. 64、Spark Streaming:StreamingContext初始化与Receiver启动原理剖析与源码分析

    一.StreamingContext源码分析 ###入口 org.apache.spark.streaming/StreamingContext.scala /** * 在创建和完成StreamCon ...

  5. 23、CacheManager原理剖析与源码分析

    一.图解 二.源码分析 ###org.apache.spark.rdd/RDD.scalal ###入口 final def iterator(split: Partition, context: T ...

  6. 22、BlockManager原理剖析与源码分析

    一.原理 1.图解 Driver上,有BlockManagerMaster,它的功能,就是负责对各个节点上的BlockManager内部管理的数据的元数据进行维护, 比如Block的增删改等操作,都会 ...

  7. 21、Shuffle原理剖析与源码分析

    一.普通shuffle原理 1.图解 假设有一个节点上面运行了4个 ShuffleMapTask,然后这个节点上只有2个 cpu core.假如有另外一台节点,上面也运行了4个ResultTask,现 ...

  8. 20、Task原理剖析与源码分析

    一.Task原理 1.图解 二.源码分析 1. ###org.apache.spark.executor/Executor.scala /** * 从TaskRunner开始,来看Task的运行的工作 ...

  9. 19、Executor原理剖析与源码分析

    一.原理图解 二.源码分析 1.Executor注册机制 worker中为Application启动的executor,实际上是启动了这个CoarseGrainedExecutorBackend进程: ...

随机推荐

  1. [国家集训队] JZPKIL

    题目链接 洛谷:https://www.luogu.org/problemnew/show/P4464 Solution 这题是真的毒....数论大杂烩,窝断断续续写了两天. 众所周知: \[ {\r ...

  2. 测试PHP-FPM的工作流中的疑惑点

    顺序比较乱,想到什么测试什么,测试环境 PHP7.2 和 MariaDB10.3.11 PHP-FPM是 master/worker 多进程模型master负责和web-server通讯,把接受到请求 ...

  3. Java中 StringBuffer StringBuilder String 区别

    String       字符串常量   不可变  使用字符串拼接时是不同的2个空间 StringBuffer  字符串变量   可变   线程安全  字符串拼接直接在字符串后追加 StringBui ...

  4. 11.15java实习生面试总结

    坐了两个小时的车,到了面试地点面了十五分钟左右就结束了,心里有一点难受,不过这也是刚开始,后面的路还长着呢,所以先把面试官问的题目记录下来. 1.C语言能否跨平台? 虽然我面的是java实习生,但是因 ...

  5. maccms 山寨站点 V10 后门

    经验证:www.maccmsv10应该是个山寨站 -------------------- 前言 苹果CMS是国内优秀的开源PHP建站系统,擅长电影程序影视系统这一块,在主流建站系统中特色鲜明,以灵活 ...

  6. python 版本号比较 重载运算符

    # -*- coding: utf-8 -*- class VersionNum(object): """ 版本号比较 默认版本以“.”分割,各位版本位数不超过3 例一: ...

  7. 将集群WEB节点静态数据迁移到共享存储器(LNMP环境)

    系统版本:Centos 6.5 机器及IP规划如下: 192.168.0.117  MySQL 192.168.0.118  nginx+php 192.168.0.123  nfs ①在NFS机器上 ...

  8. c# Directory类的常用方法

  9. Linux路由:CentOS6的多种玩法

    将一台Linux主机作路由器使用,这本是件很容易的事情,利用Linux主机强大的网络功能,很轻松就实现了.这里在虚拟机环境下设定一台CentOS主机通过另一台CentOS主机路由接入Internet网 ...

  10. ssh本机失败(ssh: connect to host localhost port 22: Connection refused)

    ssh本机失败(ssh: connect to host localhost port 22: Connection refused) 一. 问题描述 之前一直在服务上使用宝塔面板, 今天突发奇想, ...