继续前一篇的内容。前一篇内容为:

Spark中Client源码分析(一)http://www.cnblogs.com/yourarebest/p/5313006.html

DriverClient中的代码比较简单,它只有一个main函数,同时,和AppClient一样,它也有一个ClientEndpoint,只是两者的用途不一样。

1.Client

Client中唯一的main方法如下:

def main(args: Array[String]) {
if (!sys.props.contains("SPARK_SUBMIT")) {
println("WARNING: This client is deprecated and will be removed in a future version of Spark")
println("Use ./bin/spark-submit with "--master spark://host:port"")
}
val conf = new SparkConf()
val driverArgs = new ClientArguments(args)
if (!driverArgs.logLevel.isGreaterOrEqual(Level.WARN)) {
conf.set("spark.akka.logLifecycleEvents", "true")
}
conf.set("spark.rpc.askTimeout", "10")
conf.set("akka.loglevel", driverArgs.logLevel.toString.replace("WARN", "WARNING"))
Logger.getRootLogger.setLevel(driverArgs.logLevel)
//创建一个driverClient的Rpc环境,并将得到Master和client的远程引用
val rpcEnv =
RpcEnv.create("driverClient", Utils.localHostName(), 0, conf, new SecurityManager(conf))
val masterEndpoints = driverArgs.masters.map(RpcAddress.fromSparkURL).
map(rpcEnv.setupEndpointRef(Master.SYSTEM_NAME, _, Master.ENDPOINT_NAME))
//clientpoint
rpcEnv.setupEndpoint("client", new ClientEndpoint(rpcEnv, driverArgs, masterEndpoints, conf))
//启动rpc环境
rpcEnv.awaitTermination()
}

2.ClientEndpoint

ClientEndPoint可以看作给Driver传递消息的代理
属性简单,直接略过。
(1)构造函数为ClientEndPoint主构造函数
(2)onstart方法如下,

override def onStart(): Unit = {
driverArgs.cmd match {
case "launch" =>
//driver包装类,使得Worker和Driver的Rpc环境一样,做到共进退
val mainClass = "org.apache.spark.deploy.worker.DriverWrapper"
//driver类路径
val classPathConf = "spark.driver.extraClassPath"
val classPathEntries = sys.props.get(classPathConf).toSeq.flatMap { cp =>
cp.split(java.io.File.pathSeparator)
}
//driver库路径
val libraryPathConf = "spark.driver.extraLibraryPath"
val libraryPathEntries = sys.props.get(libraryPathConf).toSeq.flatMap { cp =>
cp.split(java.io.File.pathSeparator)
}
//driver Jvm参数
val extraJavaOptsConf = "spark.driver.extraJavaOptions"
val extraJavaOpts = sys.props.get(extraJavaOptsConf)
.map(Utils.splitCommandString).getOrElse(Seq.empty)
//将所有的在SparkConf中设置的属性赋值给java options的序列
val sparkJavaOpts = Utils.sparkJavaOpts(conf)
//所有的javaOpts
val javaOpts = sparkJavaOpts ++ extraJavaOpts
val command = new Command(mainClass,
Seq("{{WORKER_URL}}", "{{USER_JAR}}", driverArgs.mainClass) ++ driverArgs.driverOptions,
sys.env, classPathEntries, libraryPathEntries, javaOpts)
//将以上所有的信息封装在DriverDescription中
val driverDescription = new DriverDescription(
driverArgs.jarUrl,
driverArgs.memory,
driverArgs.cores,
driverArgs.supervise,
command)
//异步请求给master发送Driver的信息
ayncSendToMasterAndForwardReplySubmitDriverResponse
case "kill" =>
val driverId = driverArgs.driverId
ayncSendToMasterAndForwardReplyKillDriverResponse
}
}

(3)onstop方法简单,略过。
(4)receive方法如下,

override def receive: PartialFunction[Any, Unit] = {
//收到master的响应回来的Driver信息,因为master是管家,Client是老板
case SubmitDriverResponse(master, success, driverId, message) =>
logInfo(message)
if (success) {
//将当前的activeMasterEndpoint设置为响应消息的master
activeMasterEndpoint = master
//找到driver的信息然后退出JVM
pollAndReportStatus(driverId.get)
} else if (!Utils.responseFromBackup(message)) {
System.exit(-1)
}
case KillDriverResponse(master, driverId, success, message) =>
logInfo(message)
if (success) {
activeMasterEndpoint = master
pollAndReportStatus(driverId),详见下①
} else if (!Utils.responseFromBackup(message)) {
System.exit(-1)
}
}

①pollAndReportStatus方法如下,用于找到driver的信息然后退出JVM

def pollAndReportStatus(driverId: String) {
logInfo("... waiting before polling master for driver state")
Thread.sleep(5000)
logInfo("... polling master for driver state")
//master请求得到Driver的信息
val statusResponse =
activeMasterEndpoint.askWithRetryDriverStatusResponse
statusResponse.found match {
case false =>
logError(s"ERROR: Cluster master did not recognize $driverId")
System.exit(-1)
case true =>
logInfo(s"State of $driverId is ${statusResponse.state.get}")
//返回的其实是worker的信息
(statusResponse.workerId, statusResponse.workerHostPort, statusResponse.state) match {
case (Some(id), Some(hostPort), Some(DriverState.RUNNING)) =>
logInfo(s"Driver running on $hostPort ($id)")
case _ =>
}
statusResponse.exception.map { e =>
logError(s"Exception from cluster was: $e")
e.printStackTrace()
System.exit(-1)
}
System.exit(0)
}
}

【原】Spark中Client源码分析(二)的更多相关文章

  1. 【原】Spark中Client源码分析(一)

    在Spark Standalone中我们所谓的Client,它的任务其实是由AppClient和DriverClient共同完成的.AppClient是一个允许app(Client)和Spark集群通 ...

  2. 【原】Spark中Master源码分析(二)

    继续上一篇的内容.上一篇的内容为: Spark中Master源码分析(一) http://www.cnblogs.com/yourarebest/p/5312965.html 4.receive方法, ...

  3. 【原】 Spark中Worker源码分析(二)

    继续前一篇的内容.前一篇内容为: Spark中Worker源码分析(一)http://www.cnblogs.com/yourarebest/p/5300202.html 4.receive方法, r ...

  4. 【原】Spark中Master源码分析(一)

    Master作为集群的Manager,对于集群的健壮运行发挥着十分重要的作用.下面,我们一起了解一下Master是听从Client(Leader)的号召,如何管理好Worker的吧. 1.家当(静态属 ...

  5. Spark中决策树源码分析

    1.Example 使用Spark MLlib中决策树分类器API,训练出一个决策树模型,使用Python开发. """ Decision Tree Classifica ...

  6. 【原】 Spark中Worker源码分析(一)

    Worker作为对于Spark集群的健壮运行起着举足轻重的作用,作为Master的奴隶,每15s向Master告诉自己还活着,一旦主人(Master>有了任务(Application),立马交给 ...

  7. Spark RPC框架源码分析(二)RPC运行时序

    前情提要: Spark RPC框架源码分析(一)简述 一. Spark RPC概述 上一篇我们已经说明了Spark RPC框架的一个简单例子,Spark RPC相关的两个编程模型,Actor模型和Re ...

  8. Docker源码分析(二):Docker Client创建与命令执行

    1. 前言 如今,Docker作为业界领先的轻量级虚拟化容器管理引擎,给全球开发者提供了一种新颖.便捷的软件集成测试与部署之道.在团队开发软件时,Docker可以提供可复用的运行环境.灵活的资源配置. ...

  9. Spark Scheduler模块源码分析之TaskScheduler和SchedulerBackend

    本文是Scheduler模块源码分析的第二篇,第一篇Spark Scheduler模块源码分析之DAGScheduler主要分析了DAGScheduler.本文接下来结合Spark-1.6.0的源码继 ...

随机推荐

  1. MySQL的EXPLAIN命令详解(转)

    explain显示了mysql如何使用索引来处理select语句以及连接表.可以帮助选择更好的索引和写出更优化的查询语句. 使用方法,在select语句前加上explain就可以了: 如: expla ...

  2. Random.Next获取随即数

    Random random = new Random(); random.Next()--------------返回非负的一个随机数. random.Next(int  maxValue)----- ...

  3. 导入NGUI插件

    在Unity编辑器顶部菜单栏中的Assets菜单中选择Import Package,然后选择Custom Package(自定义资源包),弹出资源路径窗口,在其中找到NGUI资源包所在的位置,单击”打 ...

  4. C#<热血传奇>服务端源代码再次给力更新

    前段时间一直在忙公司项目,最近抽点空稍微把部分代码重新整理一下(代码太久没碰很多地方都忘记了 囧~~~) 此次还是更新服务端,并修正上一版里面存在的很多指针 异常BUG...  (代码比较烂,还请各位 ...

  5. CSS随手记

    html5模板 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <t ...

  6. 关于c++字符串的while(*temp++)

    首先,上一段代码 static bool reverse_str(const char *str) { const char *temp=str; while(*temp++); temp-=; // ...

  7. 为你下一个项目准备的 50 个 Bootstrap 插件

    Bootstrap是快速开发Web应用程序的前端工具包.它是一个CSS和HTML的集合,它使用了最新的浏览器技术,给你的Web开发提供了时尚的版式,表单,buttons,表格,网格系统等等. 本文向你 ...

  8. Html中如何让超链接a、图片img居中

    一.问题来源 修改博客页面时,突然想到 二.解决办法 2.1原来办法 在img和a中加入align="center",发现不行 2.2百度答案 <div align=&quo ...

  9. 一组神奇的 3D Gif 动图

    本文由 极客范 - 黄利民 翻译自 mymodernmet.欢迎加入极客翻译小组,同我们一道翻译与分享.转载请参见文章末尾处的要求. 虽然 gif 动图/动画似乎是无处不在现在了,但有些聪明人已经把 ...

  10. SNMP中文

    SNMP4J 处理中文信息时的问题 http://qsjiangs.iteye.com/blog/1966899