基于spark1.6
任务提交流程
下面所说的driver(也叫ApplicationMaster)
Spark-submit
提交一个任务到集群,通过Spark-submit 脚本启动主类,这里以WordCount为例子
#Run on a Spark standalone cluster
./bin/spark-submit \
--class org.apache.spark.examples.WordCount \
--master spark://207.184.161.138:7077 \
--executor-memory 20G \
--total-executor-cores 100 \
/path/to/examples.jar \
1000
vim spark-submit bin/spark-class =》 org.apache.spark.deploy.SparkSubmit 调用这个类的main方法
提取提交参数
通过反射拿到类的实例的引用mainClass = Class.forName(childMainClass(类名), true, loader)
在通过反射调用class cn.itcast.spark.WordCount的main方法
下面看SparkSubmit 脚本 的main方法
def main(args: Array[String]): Unit = {
val appArgs = new SparkSubmitArguments(args)
if (appArgs.verbose) {
printStream.println(appArgs)
}
//匹配任务类型
appArgs.action match {
case SparkSubmitAction.SUBMIT => submit(appArgs)
case SparkSubmitAction.KILL => kill(appArgs)
case SparkSubmitAction.REQUEST_STATUS => requestStatus(appArgs)
}
}
这里的类型是submit,调用submit方法,submit里调用了doRunMain(),把应用的类的名字传进去,然后调用了runMain,跑app的main方法
private def submit(args: SparkSubmitArguments): Unit = {
val (childArgs, childClasspath, sysProps, childMainClass) = prepareSubmitEnvironment(args)// 提取参数, 赋给元祖
def doRunMain(): Unit = {
if (args.proxyUser != null) {
val proxyUser = UserGroupInformation.createProxyUser(args.proxyUser,
UserGroupInformation.getCurrentUser())
proxyUser.doAs(new PrivilegedExceptionAction[Unit]() {
override def run(): Unit = {
//childMainClass这个是你要跑的那个类的名字(例如:org.apache.spark.examples.WordCount)
runMain(childArgs, childClasspath, sysProps, childMainClass, args.verbose)
}
})
}
}
下面看runMain方法
private def runMain(
.............
try {
//通过反射
mainClass = Class.forName(childMainClass, true, loader)
} catch {
。。。。。。
}
//反射调用实例的main方法
val mainMethod = mainClass.getMethod("main", new Array[String](0).getClass)
。。。。。。
try {
//调用App的main方法
mainMethod.invoke(null, childArgs.toArray)
} catch {
case t: Throwable =>
throw findCause(t)
}
}
SparkSubmit时序图
SparkSubmit通过反射调用了我们程序的main方法,开始执行我们的代码
通过sparkConf构造 SparkContext