spark2.2.0源码学习过程记录:Day1 Day2

Day1

就像上学时候第一节课都不是正式上课,我第一天的学习也只是看了一些博客,以及 《apache spark 源码剖析》的前面两章(概念介绍和环境搭建等)

1、先看博客,有总体感觉,预热

http://www.cnblogs.com/hframe/p/6735123.html

2、看《apache spark 源码剖析》第一章、第二章


Day2

第二天开始看源码,采取看一段书,跟一段源码的方式这天只看了第三章的第一节,然后就开始源码的学习

1、读《apache spark 源码剖析》第三章第1节, SparkContext初始化


2、源码学习

看完3.1节,从jvm工具中知道了几个类的启动顺序:SparkSubmit,repl.Main,SparkILoop
而下一节会开始讲SparkContext,所以,这里开始自己看书中提到和略过的几个代码

类:SparkSubmit

首先从命令行参数初始化SparkSubmitArguments类,这个类保存各种初始化配置
然后判断要执行的命令是SUBMIT还是KILL还是REQUEST_STATUS
KILL:使用master和submissionId杀掉该submission(使用REST protocol,只有在Standalone或Mesos模式可用)
REQUEST_STATUS:使用master和submissionId查询该submission的执行状态(使用REST protocol,只有在Standalone或Mesos模式可用)
SUBMIT:
首先加载子进程的运行时环境:包括参数、classpath、系统属性和入口类
然后使用反射、类加载的方式,重新设置运行时环境(设置成子进程需要的),然后执行下面步骤:
如果是standalone集群,则使用下面的启动方式
使用rest方式提交任务,入口类为org.apache.spark.deploy.rest.RestSubmissionClient,
如果rest方式失败,则用旧的rpc方式提交,入口类为:org.apache.spark.deploy.Client
调用上面所说类的main方法
这个类完了,下面看RestSubmissionClient
RestSubmissionClient仅仅是调用了rest接口连接master,由master端处理数据
而我们的例子中,因为是从spark shell中来的org.apache.spark.repl.Main类,所以下面看这个类的main方法
初始化日志配置
注册interrupt事件(如果是类unix系统,用户可以用ctrl c关闭程序及所有job)
创建SparkILoop,将配置项传入
SparkILoop的process方法创建了一个scala的Interpreter
Interpreter在调用loadFiles方法时调用了自身的initializeSpark方法,initializeSpark又调用了repl.Main的createSparkSession创建 sparksession和sparkcontext

上面所述的initializeSpark就是书中本节最后的代码示例部分(版本不同所以内容有所不同了),继续看下一节书

下面是看代码过程中发现的一些自己觉得有意思的小细节,记录下来,

小细节1
private val YARN = 1
private val STANDALONE = 2
private val MESOS = 4
private val LOCAL = 8
private val ALL_CLUSTER_MGRS = YARN | STANDALONE | MESOS | LOCAL
用按位或操作,前四个分别是0001,0010,0100,1000,最后一个是1111
在后面判断是否支持某个模式时,可以按位与,结果!=0则满足

小细节2
printVersionAndExit 中的SPARK_VERSION在spark-version-info.properties文件中,这个文件并不在源码中,而在编译后的spark-core的jar包中,我的是在spark-core_2.11-2.2.0.jar中

小细节3
SparkSubmit目前不支持的模式:
pyhton和r不支持Cluster deploy on standalone clusters
spark shell、spark sql、spark thrift不支持Cluster deploy模式

小细节4
如果跑的是python程序,入口类是PythonGatewayServer或PythonRunner,以后如果需要跟代码可以看一下

小细节5
如果需要一个先用本加载器加载,加载不到再用父类加载器加载的话可以参考ChildFirstURLClassLoader的实现,新建对象时把父加载器用另外的参数存储,调用父类的构造方法时父加载器参数传null,这样在loadClass时可以先用super.loadClass,报错再手动调用父加载器的loadClass方法

小细节6
scala中可以使用@tailrec注释确保写出的递归是尾递归,尾递归效率会更高

类:SparkSubmitArguments

真正解析命令行参数在这个类中
解析顺序:
解析shell传入的命令行参数,包括普通参数(比如程序入口类,作业队列名等)和spark参数
将默认文件spark-defaults.conf参数合并进spark参数去
去掉不是以spark开头的spark参数
验证各种参数满足规则

小细节1
在ui界面以及输出时,会对敏感信息(比如密码)进行编辑替换成类似*********的字符串

你可能感兴趣的:(spark2.2.0源码学习)