Spark 部署模式
(1)Standalone:獨立模式,Spark原生的簡單集羣管理器,自帶完整的服務,可單獨部署到一個集羣中,無需依賴任何其他資源管理系統,使用Standalone可以很方便地搭建一個集羣;
(2)Hadoop YARN:統一的資源管理機制,在上面可以運行多套計算框架,如MR、Storm等。根據Driver在集羣中的位置不同,分爲yarn client和yarn cluster;
(3)Apache Mesos:一個強大的分佈式資源管理框架,它允許多種不同的框架部署在其上,包括Yarn。
在實際工廠環境下使用的絕大多數的集羣管理器是Hadoop YARN
YARN Cluster模式
(1)執行腳本提交任務,實際是啓動一個SparkSubmit的JVM進程;
(2)SparkSubmit類中的main方法反射調用Client的main方法;
(3)Client創建Yarn客戶端,然後向Yarn發送執行指令:bin/java ApplicationMaster;
(4)Yarn框架收到指令後會在指定的NM中啓動ApplicationMaster;
(5)ApplicationMaster啓動Driver線程,執行用戶的作業;
(6)AM向RM註冊,申請資源;
(7)獲取資源後AM向NM發送指令:bin/java CoarseGrainedExecutorBacken;
(8)ExecutorBackend進程會接收消息,啓動計算對象Executor並跟Driver通信,註冊已經啓動的Executor;
(9)Driver分配任務並監控任務的執行。
SparkSubmit、ApplicationMaster和CoarseGrainedExecutorBacken是獨立的進程;
Client和Driver是獨立的線程;
Executor是一個對象。
程序提交入口類
任務提交SparkSubmit
打印spark操作源碼
main()方法
// 在new SparkSubmitArguments()中action默認爲Submit
action = Option(action).getOrElse(SUBMIT)
提交程序 submit(appArgs)
準備提交環境prepareSubmitEnvironment()
// 集羣
if (isYarnCluster) ==> childMainClass = "org.apache.spark.deploy.yarn.Client"
// 客戶端
if (deployMode==CLIENT) ==> childMainClass = args.mainClass("用戶類")
繼續向下執行
doRunMain()過度方法,會最終指向runMain()方法
if…else都會執行runMain,只是if裏面會判斷是否時代理用戶做一點操作
runMain()具體方法
// 通過反射,聲明Class對象並賦值
var mainClass = Utils.classForName(childMainClass)
// 在準備提交環境中,childMainClass的值爲下
childMainClass = "org.apache.spark.deploy.yarn.Client"
childMainClass = args.mainClass("用戶類")
獲取類中main方法:mainClass.getMethod(“main”, new ArrayString.getClass)
// 通過類對象獲取mainClass中的main方法
val mainMethod = mainClass.getMethod("main", new Array[String](0).getClass)
通過invoke執行main方法(): mainMethod.invoke(null, childArgs.toArray)
執行mainClass中的main方法
小結
org.apache.spark.deploy.SparkSubmit
//1.程序入口
main()
//2.提交程序
submit(appArgs)
//3.準備提交環境
val (childArgs, childClasspath, sysProps, childMainClass) = prepareSubmitEnvironment(args)
if (isYarnCluster) ==> childMainClass = "org.apache.spark.deploy.yarn.Client"
if (deployMode==CLIENT) ==> childMainClass = args.mainClass("用戶類")
//4. 過渡
doRunMain()
//5.
runMain(childArgs, childClasspath, sysProps, childMainClass, args.verbose)
//6.聲明Class對象並賦值
var mainClass: Class[_] = Utils.classForName(childMainClass)
//7.獲取mainClass中的main方法
val mainMethod = mainClass.getMethod("main", new Array[String](0).getClass)
//8.執行mainClass中的main方法
mainMethod.invoke(null, childArgs.toArray)