《深入理解SPARK:核心思想与源码分析》(第1章)

       自己牺牲了7个月的周末和下班空闲时间,通过研究Spark源码和原理,总结整理的《深入理解Spark:核心思想与源码分析》一书现在已经正式出版上市,目前亚马逊、京东、当当、天猫等网站均有销售,欢迎感兴趣的同学购买。我开始研究源码时的Spark版本是1.2.0,经过7个多月的研究和出版社近4个月的流程,Spark自身的版本迭代也很快,如今最新已经是1.6.0。目前市面上另外2本源码研究的Spark书籍的版本分别是0.9.0版本和1.2.0版本,看来这些书的作者都与我一样,遇到了这种问题。由于研究和出版都需要时间,所以不能及时跟上Spark的脚步,还请大家见谅。但是Spark核心部分的变化相对还是很少的,如果对版本不是过于追求,依然可以选择本书。

天猫当当亚马逊京东 均有销售。

为了让大家对本书有个大致了解,这里将本书第一章的内容附上:

第1章 环境准备

“凡事豫则立,不豫则废;言前定,则不跲;事前定,则不困;”

——《礼记·中庸》

本章导读:

       在深入了解一个系统的原理、实现细节之前,应当先准备好它的源码编译环境、运行环境。如果能在实际环境安装和运行Spark,显然能够提升读者对于Spark的一些感受,对系统能有个大体的印象,有经验的技术人员甚至能够猜出一些Spark采用的编程模型、部署模式等。当你通过一些途径知道了系统的原理之后,难道不会问问自己?这是怎么做到的。如果只是游走于系统使用、原理了解的层面,是永远不可能真正理解整个系统的。很多IDE本身带有调试的功能,每当你阅读源码,陷入重围时,调试能让我们更加理解运行期的系统。如果没有调试功能,不敢想象阅读源码的困难。本章的主要目的是帮助读者构建源码学习环境,主要包括以下内容:在windows环境下搭建源码阅读环境;在Linux搭建基本的执行环境;Spark的基本使用,如spark-shell。

1.1 运行环境准备

       考虑到大部分公司在开发和生成环境都采用Linux操作系统,所以笔者选用了64位的Linux。在正式安装Spark之前,先要找台好机器。为什么?因为笔者在安装、编译、调试的过程中发现Spark非常耗费内存,如果机器配置太低,恐怕会跑不起来。Spark的开发语言是Scala,而Scala需要运行在JVM之上,因而搭建Spark的运行环境应该包括JDK和Scala。

1.1.1 安装JDK    

      使用命令getconf LONG_BIT查看linux机器是32位还是64位,然后下载相应版本的JDK并安装。下载地址:http://www.oracle.com/technetwork/java/javase/downloads/index.html

配置环境:

cd ~

vim .bash_profile

添加如下配置:

export JAVA_HOME=/opt/java
export PATH=$PATH:$JAVA_HOME/bin
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar

由于笔者的机器上已经安装过openjdk,安装命令:

$ su -c "yum install java-1.7.0-openjdk"

安装完毕后,使用java –version命令查看,确认安装正常,如图1-1所示。

 

图1-1  查看java安装是否正常

1.1.2 安装Scala

下载地址:http://www.scala-lang.org/download/

选择最新的Scala版本下载,下载方法如下:

wget http://downloads.typesafe.com/scala/2.11.5/scala-2.11.5.tgz

移动到选好的安装目录,例如:

mv scala-2.11.5.tgz ~/install/

进入安装目录,执行以下命令:

chmod 755 scala-2.11.5.tgz
tar -xzvf scala-2.11.5.tgz

配置环境:

cd ~
vim .bash_profile

添加如下配置:

export SCALA_HOME=$HOME/install/scala-2.11.5
export PATH=$PATH:$SCALA_HOME/bin:$HOME/bin

安装完毕后键入scala,进入scala命令行,如图1-2所示。 

图1-2 进入Scala命令行

1.1.3安装Spark

下载地址:http://spark.apache.org/downloads.html

选择最新的Spark版本下载,下载方法如下:

wget http://archive.apache.org/dist/spark/spark-1.2.0/spark-1.2.0-bin-hadoop1.tgz

移动到选好的安装目录,如:

mv spark-1.2.0-bin-hadoop1.tgz~/install/

进入安装目录,执行以下命令:

chmod 755 spark-1.2.0-bin-hadoop1.tgz
tar -xzvf spark-1.2.0-bin-hadoop1.tgz

配置环境:

cd ~
vim .bash_profile

添加如下配置:

export SPARK_HOME=$HOME/install/spark-1.2.0-bin-hadoop1

1.2 SPARK初体验

       本节通过Spark的基本使用,让读者对Spark能有初步的认识,便于引导读者逐步深入学习。

1.2.1 运行spark-shell

要运行spark-shell,需要先对Spark进行配置。

进入Spark的conf文件夹:

cd ~/install/spark-1.2.0-bin-hadoop1/conf

拷贝一份spark-env.sh.template,命名为spark-env.sh,对它进行编辑,命令如下:

cp spark-env.sh.template spark-env.sh
vim spark-env.sh

添加如下配置:

export SPARK_MASTER_IP=127.0.0.1
export SPARK_LOCAL_IP=127.0.0.1

启动spark-shell:

cd ~/install/spark-1.2.0-bin-hadoop1/bin
./spark-shell

最后我们会看到spark启动的过程,如图1-3所示:

图1-3  Spark启动过程

从以上启动日志中我们可以看到SparkEnv、MapOutputTracker、BlockManagerMaster、DiskBlockManager、MemoryStore、HttpFileServer、SparkUI等信息。它们是做什么的?此处望文生义即可,具体内容将在后边的章节详细给出。

1.2.2 执行word count

       这一节,我们通过word count这个耳熟能详的例子来感受下Spark任务的执行过程。启动spark-shell后,会打开Scala命令行,然后按照以下步骤输入脚本:

步骤1   输入val lines = sc.textFile("../README.md", 2),执行结果如图1-4所示。

图1-4    步骤1执行结果

步骤2   输入val words = lines.flatMap(line => line.split(" ")),执行结果如图1-5所示。 

图1-5   步骤2执行结果

步骤3   输入val ones = words.map(w => (w,1)),执行结果如图1-6所示。 

图1-6   步骤3执行结果

步骤4   输入val counts = ones.reduceByKey(_ + _),执行结果如图1-7所示。

 

图1-7   步骤4执行结果

步骤5   输入counts.foreach(println),任务执行过程如图1-8和图1-9所示。输出结果如图1-10所示。 

图1-8   步骤5执行过程部分

 

图1-9   步骤5执行过程部分

 

图1-10  步骤5输出结果

在这些输出日志中,我们先是看到Spark中任务的提交与执行过程,然后看到单词计数的输出结果,最后打印一些任务结束的日志信息。有关任务的执行分析,笔者将在第5章中展开。

1.2.3 剖析spark-shell

      通过word count在spark-shell中执行的过程,我们想看看spark-shell做了什么?spark-shell中有以下一段脚本,见代码清单1-1。

代码清单1-1     spark-shell

function main() {
  if $cygwin; then
    stty -icanonmin 1 -echo > /dev/null 2>&1
    export SPARK_SUBMIT_OPTS="$SPARK_SUBMIT_OPTS -Djline.terminal=unix"
    "$FWDIR"/bin/spark-submit --class org.apache.spark.repl.Main "${SUBMISSION_OPTS[@]}" spark-shell "${APPLICATION_OPTS[@]}"
    sttyicanon echo > /dev/null 2>&1
  else
    export SPARK_SUBMIT_OPTS
    "$FWDIR"/bin/spark-submit --class org.apache.spark.repl.Main "${SUBMISSION_OPTS[@]}" spark-shell "${APPLICATION_OPTS[@]}"
  fi
}

我们看到脚本spark-shell里执行了spark-submit脚本,那么打开spark-submit脚本,发现其中包含以下脚本。

exec "$SPARK_HOME"/bin/spark-class org.apache.spark.deploy.SparkSubmit "${ORIG_ARGS[@]}"

脚本spark-submit在执行spark-class脚本时,给它增加了参数SparkSubmit 。打开spark-class脚本,其中包含以下脚本,见代码清单1-2。

代码清单1-2     spark-class

if [ -n "${JAVA_HOME}" ]; then
  RUNNER="${JAVA_HOME}/bin/java"
else
  if [ `command -v java` ]; then
    RUNNER="java"
  else
    echo "JAVA_HOME is not set" >&2
    exit 1
  fi
fi

exec "$RUNNER" -cp "$CLASSPATH" $JAVA_OPTS "[email protected]"

读到这,应该知道Spark启动了以SparkSubmit为主类的jvm进程。为便于在本地能够对Spark进程使用远程监控,给spark-class脚本增加追加以下jmx配置:

JAVA_OPTS="-XX:MaxPermSize=128m $OUR_JAVA_OPTS -Dcom.sun.management.jmxremote 
-Dcom.sun.management.jmxremote.port=10207 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false

在本地打开jvisualvm,添加远程主机,如图1-11所示:

 

图1-11  添加远程主机

右键单击已添加的远程主机,添加JMX连接,如图1-12:

 

图1-12 添加JMX连接

选择右侧的“线程”选项卡,选择main线程,然后点击“线程Dump”按钮,如图1-13。

图1-13 查看Spark线程

从dump的内容中找到线程main的信息如代码清单1-3所示。

代码清单1-3    main线程dump信息


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

"main" -
Thread [email protected]

   java.lang.Thread.State:
RUNNABLE

    at
java.io.FileInputStream.read0(Native Method)

    at
java.io.FileInputStream.
read(FileInputStream.java:210)

    at
scala.tools.jline.TerminalSupport.readCharacter(TerminalSupport.java:152)

    at
scala.tools.jline.UnixTerminal.readVirtualKey(UnixTerminal.java:125)

    at
scala.tools.jline.console.ConsoleReader.readVirtualKey(ConsoleReader.java:933)

    at
scala.tools.jline.console.ConsoleReader.readBinding(ConsoleReader.java:1136)

    at
scala.tools.jline.console.ConsoleReader.readLine(ConsoleReader.java:1218)

    at
scala.tools.jline.console.ConsoleReader.readLine(ConsoleReader.java:1170)

    at
org.apache.spark.repl.SparkJLineReader.readOneLine(SparkJLineReader.scala:80)

    at
scala.tools.nsc.interpreter.InteractiveReader$class.readLine(InteractiveReader.scala:43)

    at
org.apache.spark.repl.SparkJLineReader.readLine(SparkJLineReader.scala:25)

    at
org.apache.spark.repl.SparkILoop.readOneLine$1(SparkILoop.scala:619)

    at
org.apache.spark.repl.SparkILoop.innerLoop$1(SparkILoop.scala:636)

    at
org.apache.spark.repl.SparkILoop.loop(SparkILoop.scala:641)

    at
org.apache.spark.repl.SparkILoop$$anonfun$process$1.apply$mcZ$sp(SparkILoop.scala:968)

    at
org.apache.spark.repl.SparkILoop$$anonfun$process$1.apply(SparkILoop.scala:916)

    at
org.apache.spark.repl.SparkILoop$$anonfun$process$1.apply(SparkILoop.scala:916)

    at
scala.tools.nsc.util.ScalaClassLoader$.savingContextLoader(ScalaClassLoader.scala:135)

    at
org.apache.spark.repl.SparkILoop.process(SparkILoop.scala:916)

    at
org.apache.spark.repl.SparkILoop.process(SparkILoop.scala:1011)

    at
org.apache.spark.repl.Main$.main(Main.scala:31)

    at
org.apache.spark.repl.Main.main(Main.scala)

    at
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

    at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)

    at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

    at
java.lang.reflect.Method.invoke(Method.java:606)

    at
org.apache.spark.deploy.SparkSubmit$.launch(SparkSubmit.scala:358)

    at
org.apache.spark.deploy.SparkSubmit$.main(SparkSubmit.scala:75)

    at
org.apache.spark.deploy.SparkSubmit.main(SparkSubmit.scala)
 

从main线程的栈信息中看出程序的调用顺序:SparkSubmit.main→repl.Main→SparkILoop.process。SparkILoop.process方法中会调用initializeSpark方法,initializeSpark的实现见代码清单1-4。

代码清单1-4     initializeSpark的实现


1

2

3

4

5

6

7

8

9

10

11

12

def
initializeSpark() {

intp.beQuietDuring
{

      command("""

         @transient val
sc = {

           val
_sc = org.apache.spark.repl.Main.interp.createSparkContext()

           println("Spark
context available as sc."
)

           _sc

         }

        """)

      command("import
org.apache.spark.SparkContext._"
)

    }

  } 

我们看到initializeSpark调用了createSparkContext方法,createSparkContext的实现,见代码清单1-5。

代码清单1-5    createSparkContext的实现


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

def
createSparkContext(): SparkContext = {

 
val execUri = System.getenv(
"SPARK_EXECUTOR_URI")

 
val jars = SparkILoop.getAddedJars

 
val conf = 
new SparkConf()

      .setMaster(getMaster())

      .setAppName("Spark
shell"
)

      .setJars(jars)

      .set("spark.repl.class.uri",
intp.classServer.uri)

 
if
 (execUri
!= 
null)
{

 
  conf.set(
"spark.executor.uri",
execUri)

 
}

 
sparkContext = 
new SparkContext(conf)

 
logInfo(
"Created
spark context.."
)

 
sparkContext

}

这里最终使用SparkConf和SparkContext来完成初始化,具体内容将在“第3章SparkContext的初始化”讲解。代码分析中涉及的repl主要用于与Spark实时交互。

1.3 阅读环境准备

       准备Spark阅读环境,同样需要一台好机器。笔者调试源码的机器的内存是8GB。源码阅读的前提是首先在IDE环境中打包、编译通过。常用的IDE有 IntelliJ IDEA、Eclipse,笔者选择用Eclipse编译Spark,原因有二:一是由于使用多年对它比较熟悉,二是社区中使用Eclipse编译Spark的资料太少,在这里可以做个补充。笔者在windows系统编译Spark源码,除了安装JDK外,还需要安装以下工具。

(1)安装Scala

       由于Spark 1.20版本的sbt里指定的Scala版本是2.10.4,具体见Spark源码目录下的文件\project\plugins.sbt中,有一行:scalaVersion := "2.10.4"。所以选择下载scala-2.10.4.msi,下载地址:http://www.scala-lang.org/download/下载完毕,安装scala-2.10.4.msi。

(2)安装SBT

由于Scala使用SBT作为构建工具,所以需要下载SBT。下载地址: http://www.scala-sbt.org/,下载最新的安装包sbt-0.13.8.msi并安装。

(3)安装Git Bash

      由于Spark源码使用Git作为版本控制工具,所以需要下载Git的客户端工具,笔者推荐使用Git Bash,因为它更符合Linux下的操作习惯。下载地址:http://msysgit.github.io/,下载最新的版本并安装。

(4)安装Eclipse Scala IDE插件

      Eclipse通过强大的插件方式支持各种IDE工具的集成,要在Eclipse中编译、调试、运行Scala程序,就需要安装Eclipse Scala IDE插件。下载地址:http://scala-ide.org/download/current.html

      由于笔者本地的Eclipse版本是Eclipse 4.4 (Luna),所以我选择安装插件http://download.scala-ide.org/sdk/lithium/e44/scala211/stable/site,如图1-14:

 

图1-14   Eclipse Scala IDE插件安装地址

     在Eclipse中选择“Help”菜单,然后选择“Install New Software…”选项,打开Install对话框,如图1-15所示:

图1-15  安装Scala IDE插件

       点击“Add…”按钮,打开“Add Repository”对话框,输入插件地址,如1-16图所示: 

图1-16  添加Scala IDE插件地址

      全选插件的内容,完成安装,如图1-17所示: 

图1-17  安装Scala IDE插件

1.4 SPARK源码编译与调试

1.下载Spark源码

       首先,访问Spark官网http://spark.apache.org/,如图1-18所示:

 

图1-18 Spark官网

       点击“Download Spark”按钮,在下一个页面找到git地址,如图1-19所示: 

图1-19  Spark官方git地址

        打开Git Bash工具,输入git clone git://github.com/apache/spark.git命令将源码下载到本地,如1-20图所示:

 

图1-20下载Spark源码

2.构建Scala应用

       使用cmd命令行进到Spark根目录,执行sbt命令。会下载和解析很多jar包,要等很长的时间,笔者大概花费了一个多小时,才执行完。

3.使用sbt生成eclipse工程文件

       等sbt提升符>出现后,输入eclipse命令,开始生成eclipse工程文件,也需要花费很长的时间,笔者本地大致花费了40分钟。完成时的状况,如图1-21所示: 

图1-21  sbt编译过程

       现在我们查看Spark下的子文件夹,发现其中都生成了.project和.classpath文件。比如mllib项目下就生成了.project和.classpath文件,如图1-22所示: 

图1-22 sbt生成的项目文件

4.编译Spark源码

       由于Spark使用Maven作为项目管理工具,所以需要将Spark项目作为Maven项目导入到Eclipse中,如1-23图所示: 

图1-23  导入Maven项目

       点击Next按钮进入下一个对话框,如图1-24所示:

 

图1-24 选择Maven项目

       全选所有项目,点击finish按钮。这样就完成了导入,如图1-25所示:

 

图1-25 导入完成的项目

       导入完成后,需要设置每个子项目的build path。右键单击每个项目,选择“Build Path”→“Configure Build Path…”,打开Build Path对话框,如图1-26: 

图1-26 Java编译目录

      点击“Add External JARs…”按钮,将Spark项目下的lib_managed文件夹的子文件夹bundles和jars内的jar包添加进来。


注意:lib_managed/jars文件夹下有很多打好的spark的包,比如:spark-catalyst_2.10-1.3.2-SNAPSHOT.jar。这些jar包有可能与你下载的Spark源码的版本不一致,导致你在调试源码时,发生jar包冲突。所以请将它们排除出去。



 

       Eclipse在对项目编译时,笔者本地出现了很多错误,有关这些错误的解决见附录H。所有错误解决后运行mvn clean install,如图1-27所示: 

图1-27 编译成功

5.调试Spark源码

       以Spark源码自带的JavaWordCount为例,介绍如何调试Spark源码。右键单击JavaWordCount.java,选择“Debug As”→“Java Application”即可。如果想修改配置参数,右键单击JavaWordCount.java,选择“Debug As”→“Debug Configurations…”,从打开的对话框中选择JavaWordCount,在右侧标签可以修改Java执行参数、JRE、classpath、环境变量等配置,如图1-28所示:

 

图1-28源码调试

       读者也可以在Spark源码中设置断点,进行跟踪调试。

1.5 小结

       本章通过引导大家在Linux操作系统下搭建基本的执行环境,并且介绍spark-shell等脚本的执行,目的无法是为了帮助读者由浅入深的进行Spark源码的学习。由于目前多数开发工作都在Windows系统下,并且Eclipse有最广大的用户群,即便是一些开始使用IntelliJ的用户对Eclipse也不陌生,所以在Windows环境下搭建源码阅读环境时,选择这些最常用的工具,希望能降低读者的学习门槛,并且替大家节省时间。

时间: 2016-01-15

《深入理解SPARK:核心思想与源码分析》(第1章)的相关文章

《深入理解Spark:核心思想与源码分析》——2.3节Spark基本设计思想

2.3 Spark基本设计思想2.3.1 Spark模块设计 整个Spark主要由以下模块组成: Spark Core:Spark的核心功能实现,包括:SparkContext的初始化(Driver Application通过SparkContext提交).部署模式.存储体系.任务提交与执行.计算引擎等. Spark SQL:提供SQL处理能力,便于熟悉关系型数据库操作的工程师进行交互查询.此外,还为熟悉Hadoop的用户提供Hive SQL处理能力. Spark Streaming:提供流式计

《深入理解Spark:核心思想与源码分析》——第1章环境准备

第1章 环 境 准 备 凡事豫则立,不豫则废:言前定,则不跲:事前定,则不困. -<礼记·中庸> 本章导读 在深入了解一个系统的原理.实现细节之前,应当先准备好它的源码编译环境.运行环境.如果能在实际环境安装和运行Spark,显然能够提升读者对于Spark的一些感受,对系统能有个大体的印象,有经验的技术人员甚至能够猜出一些Spark采用的编程模型.部署模式等.当你通过一些途径知道了系统的原理之后,难道不会问问自己:"这是怎么做到的?"如果只是游走于系统使用.原理了解的层面,

《深入理解Spark:核心思想与源码分析》——第3章SparkContext的初始化

第3章 SparkContext的初始化 道生一, 一生二, 二生三, 三生万物. -<道德经> 本章导读 SparkContext的初始化是Driver应用程序提交执行的前提,本章内容以local模式为主,并按照代码执行顺序讲解,这将有助于首次接触Spark的读者理解源码.读者朋友如果能边跟踪代码,边学习本章内容,也许是快速理解SparkContext初始化过程的便捷途径.已经熟练使用Spark的开发人员可以选择跳过本章内容. 本章将在介绍SparkContext初始化过程的同时,向读者介绍

《深入理解Spark:核心思想与源码分析》——1.4节Spark源码编译与调试

1.4 Spark源码编译与调试 1.下载Spark源码 首先,访问Spark官网http://spark.apache.org/,如图1-18所示. 2.构建Scala应用 使用cmd命令行进到Spark根目录,执行sbt命令.会下载和解析很多jar包,要等很长时间,笔者大概花了一个多小时才执行完. 3.使用sbt生成Eclipse工程文件 等sbt提示符(>)出现后,输入Eclipse命令,开始生成Eclipse工程文件,也需要花费很长时间,笔者本地大致花了40分钟.完成时的状况如图1-21

《深入理解Spark:核心思想与源码分析》——3.1节SparkContext概述

3.1 SparkContext概述 Spark Driver用于提交用户应用程序,实际可以看作Spark的客户端.了解Spark Driver的初始化,有助于读者理解用户应用程序在客户端的处理过程. Spark Driver的初始化始终围绕着SparkContext的初始化.SparkContext可以算得上是所有Spark应用程序的发动机引擎,轿车要想跑起来,发动机首先要启动.SparkContext初始化完毕,才能向Spark集群提交任务.在平坦的公路上,发动机只需以较低的转速.较低的功率

《深入理解Spark:核心思想与源码分析》——1.5节小结

1.5 小结 本章通过引导大家在Linux操作系统下搭建基本的执行环境,并且介绍spark-shell等脚本的执行,来帮助读者由浅入深地进行Spark源码的学习.由于目前多数开发工作都在Windows系统下进行,并且Eclipse有最广大的用户群,即便是一些开始使用IntelliJ的用户对Eclipse也不陌生,所以在Windows环境下搭建源码阅读环境时,选择这些最常用的工具,能降低读者的学习门槛,并且替大家节省时间.

《深入理解Spark:核心思想与源码分析》——2.2节Spark基础知识

2.2 Spark基础知识 1.版本变迁 经过4年多的发展,Spark目前的版本是1.4.1.我们简单看看它的版本发展过程. 1)Spark诞生于UCBerkeley的AMP实验室(2009). 2)Spark正式对外开源(2010年). 3)Spark 0.6.0版本发布(2012-10-15),进行了大范围的性能改进,增加了一些新特性,并对Standalone部署模式进行了简化. 4)Spark 0.6.2版本发布(2013-02-07),解决了一些bug,并增强了系统的可用性. 5)Spa

《深入理解Spark:核心思想与源码分析》——3.6节创建任务调度器TaskScheduler

3.6 创建任务调度器TaskScheduler TaskScheduler也是SparkContext的重要组成部分,负责任务的提交,并且请求集群管理器对任务调度.TaskScheduler也可以看做任务调度的客户端.创建TaskScheduler的代码如下. private[spark] var (schedulerBackend, taskScheduler) = SparkContext.createTaskScheduler(this, master) createTaskSchedu

《深入理解Spark:核心思想与源码分析》——2.4节Spark基本架构

2.4 Spark基本架构从集群部署的角度来看,Spark集群由以下部分组成:Cluster Manager:Spark的集群管理器,主要负责资源的分配与管理.集群管理器分配的资源属于一级分配,它将各个Worker上的内存.CPU等资源分配给应用程序,但是并不负责对Executor的资源分配.目前,Standalone.YARN.Mesos.EC2等都可以作为Spark的集群管理器.Worker:Spark的工作节点.对Spark应用程序来说,由集群管理器分配得到资源的Worker节点主要负责以

《深入理解Spark:核心思想与源码分析》——3.7节创建和启动DAGScheduler

3.7 创建和启动DAGSchedulerDAGScheduler主要用于在任务正式交给TaskSchedulerImpl提交之前做一些准备工作,包括:创建Job,将DAG中的RDD划分到不同的Stage,提交Stage,等等.创建DAG-Scheduler的代码如下. @volatile private[spark] var dagScheduler: DAGScheduler = _ dagScheduler = new DAGScheduler(this) DAGScheduler的数据结