从零开始学习Spark--第5章 SparkContext类分析

1. SparkContext类是Spark的关键类,代码在这里:./core/src/main/scala/org/apache/spark/SparkContext.scala。SparkContext是Spark的入口,负责连接Spark集群,创建RDD,累积量和广播量等。从本质上来说,SparkContext是Spark的对外接口,负责向调用这提供Spark的各种功能。它的作用是一个容器。SparkContext类非常简洁,大多数函数体只有几行代码。


2. scala完全兼容java,可以直接使用java的代码,所以引入了很多java库和hadoop库。


3. SparkContext.scala实现了一个class SparkContext和一个object SparkContext。
    Scala语言不能定义静态成员,于是就出现了单例对象 singleton object,除了用object关键字代替了class之外,单例对象的定义跟class的定义完全一致。
    如果单例对象和某个类的名字是一样的,如SparkContext,那么,它就是这个类的伴生对象-companion object。类和它的伴生对象必须定义在一个源文件里。类,被成为是这个单例对象的伴生类-companion class。类和它的伴生对象可以互相访问其私有成员。
    单例对象有什么意义呢?
    单例对象没有类型,所以,如果只有object SparkContext,就不能创建class SparkContext对象,那么,在需要把SparkContext作为参数的函数调用就不用使用了。因此,object SparkContext的类型,是由它的伴生类 class SparkContext定义的。
    可以使用类型调用单例对象的方法,也可以用类的实例变量指代单例对象,并把它传递给需要类型参数的方法。
    单例对象不带参数。
    单例对象不是用new关键字实例化的,所以不能传递给它实例化参数。
    单例对象在第一次被访问的时候才会被实例化。
    如果单例对象没有伴生类,那么它就是独立对象-standalone object,可以作为相关功能方法的工具类,或者是scala应用的入口点。




4. class SparkContext的定义


class SparkContext(
    val master: String,
    val appName: String,
    val sparkHome: String = null,
    val jars: Seq[String] = Nil,
    val environment: Map[String, String] = Map(),
    val preferredNodeLocationData: scala.collection.Map[String, scala.collection.Set[SplitInfo]] = scala.collection.immutable.Map())
  extends Logging {
...
}


    对scala语言来说,如下这些:
    val master: String,
    val appName: String,
    val sparkHome: String = null,
    val jars: Seq[String] = Nil,
    val environment: Map[String, String] = Map(),
    val preferredNodeLocationData: scala.collection.Map[String, scala.collection.Set[SplitInfo]] = scala.collection.immutable.Map()
    是类SparkContext的参数,scala会根据这些类参数,创建带有这些类参数的主构造器。这些参数,也就成了类的字段。


    在SparkContext类的其他既不是函数定义,又不是字段的语句,如:
    initLogging()
    都编译到主构造器。


5. class SparkContext是extends了Logging。Logging定义在Logging.scal,是一个trait。
    trait,也就是特质。trait封装方法和字段。把trait混入到类中,就可以重用它们。一个类,可以混入任意多个特制。
    你可以近似将它视为Java的接口interface,特质,在行为上跟interface非常相似。唯一的差别在于,interface声明函数,但不实现它们,trait可以实现函数。
    trait跟class的差别在于,trait没有任何类参数,trait调用的方法是动态绑定的。


6. private[spark] val env 
    定义了一个私有的不可变量env,这里的[spark],是一种保护的作用域,这个意思是,env这个量在包spark是可见的,在包spark之外是不可见的。


7. import org.apache.spark.rdd._
    "_"的意识类似Java里的import java.io.*里的"*",引入所有。


8. @volatile
    @这种语法叫注解,跟Java一样。@volatile注解,通知编译器,被注解的变量将被多个线程使用。


9. implicit
    隐式操作。


10. SparkContext创建时候的master参数是为了创建taskSchedule。
10.1 如果master是"local",则创建LocalScheduler,它的源代码在此:
    ./src/main/scala/org/apache/spark/scheduler/local/LocalScheduler.scala
    LocalScheduler类继承了trait特质TaskScheduler。
10.2 如果master是"spark",则创建SparkDeploySchedulerBackend。在SparkDeploySchedulerBackend的start函数,会启动一个Client对象,连接到Spark集群。


10.3 textFile函数的运行
    textFile调用hadoopFile函数,返回一个RDD结构,然后把它做map,返回另外一个RDD结构。
    hadoopFile函数创建了HadoopRDD类。
    HadoopRDD类继承抽象类RDD。
    当HadoopRDD执行map的时候,返回的是MappedRDD,lazy运算。

你可能感兴趣的:(从零开始学习Spark)