上一篇博客中提到了org.apache.spark.launcher.Main這個類落追,用來生成供spark-class中exec執(zhí)行的具體的command,本文我們就來具體看一下這個類的實現(xiàn)機制涯肩。
首先使用一張圖來概括一下Main的實現(xiàn)原理和機制轿钠,然后再進行詳細說明,俗話說“有圖有真相病苗!”
下面我們對這張圖進行說明:
1疗垛、首先在spark-class中通過Main [class] [classArgs]的方式將SparkSubmit或者Master、Worker以參數(shù)的方式傳入
2硫朦、Main中的main方法獲取到spark-class傳過來的className贷腕,判斷是否為SparkSubmit
3、如果是SparkSubmit就通過實例化SparkSubmitCommandBuilder并調(diào)用buildCommand方法來創(chuàng)建供spark-class中exec執(zhí)行的command
4阵幸、如果是其他的類(例如Master或者Worker等)就會實例化SparkClassCommandBuilder并調(diào)用buildCommand方法來創(chuàng)建供spark-class中exec執(zhí)行的command
5、3和4生成的command最終都會交給spark-class中的exec來執(zhí)行芽世,生成具體的進程:根據(jù)3生成的command創(chuàng)建的就是SparkSubmit進程挚赊,用來提交應(yīng)用程序;根據(jù)4生成的command創(chuàng)建的就是Master济瓢、Worker等進程荠割。
下面是Main類的main()方法,供大家參考:
public static void main(String[] argsArray) throws Exception {
checkArgument(argsArray.length > 0, "Not enough arguments: missing class name.");
List<String> args = new ArrayList<String>(Arrays.asList(argsArray));
String className = args.remove(0);
boolean printLaunchCommand = !isEmpty(System.getenv("SPARK_PRINT_LAUNCH_COMMAND"));
AbstractCommandBuilder builder;
if (className.equals("org.apache.spark.deploy.SparkSubmit")) {
try {
builder = new SparkSubmitCommandBuilder(args);
} catch (IllegalArgumentException e) {
printLaunchCommand = false;
System.err.println("Error: " + e.getMessage());
System.err.println();
MainClassOptionParser parser = new MainClassOptionParser();
try {
parser.parse(args);
} catch (Exception ignored) {
// Ignore parsing exceptions.
}
List<String> help = new ArrayList<String>();
if (parser.className != null) {
help.add(parser.CLASS);
help.add(parser.className);
}
help.add(parser.USAGE_ERROR);
builder = new SparkSubmitCommandBuilder(help);
}
} else {
builder = new SparkClassCommandBuilder(className, args);
}
Map<String, String> env = new HashMap<String, String>();
List<String> cmd = builder.buildCommand(env);
if (printLaunchCommand) {
System.err.println("Spark Command: " + join(" ", cmd));
System.err.println("========================================");
}
if (isWindows()) {
System.out.println(prepareWindowsCommand(cmd, env));
} else {
// In bash, use NULL as the arg separator since it cannot be used in an argument.
List<String> bashCmd = prepareBashCommand(cmd, env);
for (String c : bashCmd) {
System.out.print(c);
System.out.print('\0');
}
}
}
有興趣的朋友可以深入研究一下command構(gòu)造的內(nèi)部機制旺矾,本文只是上一篇博客的補充蔑鹦,避免大家對Main的內(nèi)部工作機制產(chǎn)生疑惑。
接下來的文章我們將對Spark的內(nèi)核架構(gòu)進行分析箕宙。
本文為原創(chuàng)嚎朽,歡迎轉(zhuǎn)載,轉(zhuǎn)載請注明出處柬帕、作者哟忍,謝謝狡门!