Skip to content

Commit 1590141

Browse files
committed
Address review comments
1 parent 45ccdea commit 1590141

File tree

6 files changed

+48
-27
lines changed

6 files changed

+48
-27
lines changed

yarn/alpha/src/main/scala/org/apache/spark/deploy/yarn/Client.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ private[spark] class Client(
125125
Option(report.getClientToken).getOrElse("")
126126
}
127127

128-
private[spark] object Client {
128+
object Client {
129129
def main(argStrings: Array[String]) {
130130
if (!sys.props.contains("SPARK_SUBMIT")) {
131131
println("WARNING: This client is deprecated and will be removed in a " +
@@ -145,5 +145,7 @@ private[spark] object Client {
145145
Console.err.println(e.getMessage)
146146
System.exit(1)
147147
}
148+
149+
System.exit(0)
148150
}
149151
}

yarn/common/src/main/scala/org/apache/spark/deploy/yarn/ClientArguments.scala

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -47,22 +47,20 @@ private[spark] class ClientArguments(args: Array[String], sparkConf: SparkConf)
4747
"spark.yarn.executor.memoryOverhead", YarnSparkHadoopUtil.DEFAULT_MEMORY_OVERHEAD)
4848

4949
parseArgs(args.toList)
50-
loadDefaultArgs()
50+
loadEnvironmentArgs()
5151
validateArgs()
5252

5353
/** Load any default arguments provided through environment variables and Spark properties. */
54-
private def loadDefaultArgs(): Unit = {
54+
private def loadEnvironmentArgs(): Unit = {
5555
// For backward compatibility, SPARK_YARN_DIST_{ARCHIVES/FILES} should be resolved to hdfs://,
5656
// while spark.yarn.dist.{archives/files} should be resolved to file:// (SPARK-2051).
57-
files = Option(files).orElse(sys.env.get("SPARK_YARN_DIST_FILES")).orNull
5857
files = Option(files)
59-
.orElse(sparkConf.getOption("spark.yarn.dist.files"))
60-
.map(p => Utils.resolveURIs(p))
58+
.orElse(sys.env.get("SPARK_YARN_DIST_FILES"))
59+
.orElse(sparkConf.getOption("spark.yarn.dist.files").map(p => Utils.resolveURIs(p)))
6160
.orNull
62-
archives = Option(archives).orElse(sys.env.get("SPARK_YARN_DIST_ARCHIVES")).orNull
6361
archives = Option(archives)
64-
.orElse(sparkConf.getOption("spark.yarn.dist.archives"))
65-
.map(p => Utils.resolveURIs(p))
62+
.orElse(sys.env.get("SPARK_YARN_DIST_ARCHIVES"))
63+
.orElse(sparkConf.getOption("spark.yarn.dist.archives").map(p => Utils.resolveURIs(p)))
6664
.orNull
6765
}
6866

@@ -71,6 +69,7 @@ private[spark] class ClientArguments(args: Array[String], sparkConf: SparkConf)
7169
* This is intended to be called only after the provided arguments have been parsed.
7270
*/
7371
private def validateArgs(): Unit = {
72+
// TODO: memory checks are outdated (SPARK-3476)
7473
Map[Boolean, String](
7574
(numExecutors <= 0) -> "You must specify at least 1 executor!",
7675
(amMemory <= amMemoryOverhead) -> s"AM memory must be > $amMemoryOverhead MB",

yarn/common/src/main/scala/org/apache/spark/deploy/yarn/ClientBase.scala

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,9 @@ import org.apache.hadoop.yarn.api.protocolrecords._
3636
import org.apache.hadoop.yarn.api.records._
3737
import org.apache.hadoop.yarn.conf.YarnConfiguration
3838
import org.apache.hadoop.yarn.util.Records
39+
3940
import org.apache.spark.{Logging, SecurityManager, SparkConf, SparkContext, SparkException}
41+
import org.apache.spark.util.Utils
4042

4143
/**
4244
* The entry point (starting in Client#main() and Client#run()) for launching Spark on YARN.
@@ -217,7 +219,6 @@ private[spark] trait ClientBase extends Logging {
217219
sparkConf.set(CONF_SPARK_YARN_SECONDARY_JARS, cachedSecondaryJarLinks.mkString(","))
218220
}
219221

220-
UserGroupInformation.getCurrentUser().addCredentials(credentials)
221222
localResources
222223
}
223224

@@ -360,9 +361,9 @@ private[spark] trait ClientBase extends Logging {
360361
}
361362
val amClass =
362363
if (isLaunchingDriver) {
363-
classOf[ApplicationMaster].getName()
364+
Utils.getFormattedClassName(ApplicationMaster)
364365
} else {
365-
classOf[ApplicationMaster].getName().replace("ApplicationMaster", "ExecutorLauncher")
366+
Utils.getFormattedClassName(ExecutorLauncher)
366367
}
367368
val userArgs = args.userArgs.flatMap { arg =>
368369
Seq("--arg", YarnSparkHadoopUtil.escapeForShell(arg))
@@ -400,6 +401,8 @@ private[spark] trait ClientBase extends Logging {
400401
val securityManager = new SecurityManager(sparkConf)
401402
amContainer.setApplicationACLs(YarnSparkHadoopUtil.getApplicationAclsForYarn(securityManager))
402403
setupSecurityToken(amContainer)
404+
UserGroupInformation.getCurrentUser().addCredentials(credentials)
405+
403406
amContainer
404407
}
405408

@@ -409,22 +412,24 @@ private[spark] trait ClientBase extends Logging {
409412
*
410413
* @param returnOnRunning Whether to also return the application state when it is RUNNING.
411414
* @param logApplicationReport Whether to log details of the application report every iteration.
415+
* @param shouldKeepMonitoring The condition to keep monitoring.
412416
* @return state of the application, one of FINISHED, FAILED, KILLED, and RUNNING.
413417
*/
414418
def monitorApplication(
415419
appId: ApplicationId,
416420
returnOnRunning: Boolean = false,
417-
logApplicationReport: Boolean = true): YarnApplicationState = {
421+
logApplicationReport: Boolean = true,
422+
shouldKeepMonitoring: () => Boolean = () => true): YarnApplicationState = {
418423
val interval = sparkConf.getLong("spark.yarn.report.interval", 1000)
419-
while (true) {
424+
var firstIteration = true
425+
while (shouldKeepMonitoring()) {
420426
Thread.sleep(interval)
421427
val report = getApplicationReport(appId)
422428
val state = report.getYarnApplicationState
423429

424430
if (logApplicationReport) {
425-
logInfo(s"Application report from ResourceManager for application ${appId.getId} " +
426-
s"(state: $state)")
427-
logDebug("\n" +
431+
logInfo(s"Application report from ResourceManager for app ${appId.getId} (state: $state)")
432+
val details = "\n" +
428433
s"\t full application identifier: $appId\n" +
429434
s"\t clientToken: ${getClientToken(report)}\n" +
430435
s"\t appDiagnostics: ${report.getDiagnostics}\n" +
@@ -435,7 +440,14 @@ private[spark] trait ClientBase extends Logging {
435440
s"\t yarnAppState: $state\n" +
436441
s"\t distributedFinalState: ${report.getFinalApplicationStatus}\n" +
437442
s"\t appTrackingUrl: ${report.getTrackingUrl}\n" +
438-
s"\t appUser: ${report.getUser}")
443+
s"\t appUser: ${report.getUser}"
444+
445+
// Log report details every iteration if DEBUG is enabled, otherwise only the first
446+
if (log.isDebugEnabled) {
447+
logDebug(details)
448+
} else if (firstIteration) {
449+
logInfo(details)
450+
}
439451
}
440452

441453
if (state == YarnApplicationState.FINISHED ||
@@ -447,6 +459,8 @@ private[spark] trait ClientBase extends Logging {
447459
if (returnOnRunning && state == YarnApplicationState.RUNNING) {
448460
return state
449461
}
462+
463+
firstIteration = false
450464
}
451465
// Never reached, but keeps compiler happy
452466
throw new SparkException("While loop is depleted! This should never happen...")

yarn/common/src/main/scala/org/apache/spark/deploy/yarn/YarnSparkHadoopUtil.scala

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ import org.apache.spark.util.Utils
4242
/**
4343
* Contains util methods to interact with Hadoop from spark.
4444
*/
45-
private[spark] class YarnSparkHadoopUtil extends SparkHadoopUtil {
45+
class YarnSparkHadoopUtil extends SparkHadoopUtil {
4646

4747
override def transferCredentials(source: UserGroupInformation, dest: UserGroupInformation) {
4848
dest.addCredentials(source.getCredentials())
@@ -83,7 +83,7 @@ private[spark] class YarnSparkHadoopUtil extends SparkHadoopUtil {
8383

8484
}
8585

86-
private[spark] object YarnSparkHadoopUtil {
86+
object YarnSparkHadoopUtil {
8787
// Additional memory overhead - in mb.
8888
val DEFAULT_MEMORY_OVERHEAD = 384
8989

@@ -136,7 +136,9 @@ private[spark] object YarnSparkHadoopUtil {
136136
m.appendReplacement(sb, Matcher.quoteReplacement(replace))
137137
}
138138
m.appendTail(sb)
139-
env(parts(0)) = sb.toString
139+
// This treats the environment variable as path variable delimited by `File.pathSeparator`
140+
// This is kept for backward compatibility and consistency with Hadoop's behavior
141+
addPathToEnvironment(env, parts(0), sb.toString)
140142
}
141143
}
142144
}

yarn/common/src/main/scala/org/apache/spark/scheduler/cluster/YarnClientSchedulerBackend.scala

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,11 @@ private[spark] class YarnClientSchedulerBackend(
3434
minRegisteredRatio = 0.8
3535
}
3636

37-
var client: Client = null
38-
var appId: ApplicationId = null
39-
var stopping: Boolean = false
40-
var totalExpectedExecutors = 0
37+
private var client: Client = null
38+
private var appId: ApplicationId = null
39+
private var stopping: Boolean = false
40+
private var totalExpectedExecutors = 0
41+
private def isStopping(): Boolean = stopping
4142

4243
/**
4344
* Create a Yarn client to submit an application to the ResourceManager.
@@ -120,7 +121,8 @@ private[spark] class YarnClientSchedulerBackend(
120121
assert(client != null && appId != null, "Application has not been submitted yet!")
121122
val t = new Thread {
122123
override def run() {
123-
val state = client.monitorApplication(appId, logApplicationReport = false) // blocking
124+
val state = client.monitorApplication(
125+
appId, logApplicationReport = false, shouldKeepMonitoring = isStopping) // blocking
124126
if (state == YarnApplicationState.FINISHED ||
125127
state == YarnApplicationState.KILLED ||
126128
state == YarnApplicationState.FAILED) {

yarn/stable/src/main/scala/org/apache/spark/deploy/yarn/Client.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ private[spark] class Client(
123123
Option(report.getClientToAMToken).map(_.toString).getOrElse("")
124124
}
125125

126-
private[spark] object Client {
126+
object Client {
127127
def main(argStrings: Array[String]) {
128128
if (!sys.props.contains("SPARK_SUBMIT")) {
129129
println("WARNING: This client is deprecated and will be removed in a " +
@@ -143,5 +143,7 @@ private[spark] object Client {
143143
Console.err.println(e.getMessage)
144144
System.exit(1)
145145
}
146+
147+
System.exit(0)
146148
}
147149
}

0 commit comments

Comments
 (0)