Skip to content
Snippets Groups Projects
Commit aa40c442 authored by Marcelo Vanzin's avatar Marcelo Vanzin Committed by Andrew Or
Browse files

[SPARK-8059] [YARN] Wake up allocation thread when new requests arrive.

This should help reduce latency for new executor allocations.

Author: Marcelo Vanzin <vanzin@cloudera.com>

Closes #6600 from vanzin/SPARK-8059 and squashes the following commits:

8387a3a [Marcelo Vanzin] [SPARK-8059] [yarn] Wake up allocation thread when new requests arrive.
parent bfbf12b3
No related branches found
No related tags found
No related merge requests found
......@@ -67,6 +67,7 @@ private[spark] class ApplicationMaster(
@volatile private var reporterThread: Thread = _
@volatile private var allocator: YarnAllocator = _
private val allocatorLock = new Object()
// Fields used in client mode.
private var rpcEnv: RpcEnv = null
......@@ -359,7 +360,9 @@ private[spark] class ApplicationMaster(
}
logDebug(s"Number of pending allocations is $numPendingAllocate. " +
s"Sleeping for $sleepInterval.")
Thread.sleep(sleepInterval)
allocatorLock.synchronized {
allocatorLock.wait(sleepInterval)
}
} catch {
case e: InterruptedException =>
}
......@@ -546,8 +549,15 @@ private[spark] class ApplicationMaster(
override def receiveAndReply(context: RpcCallContext): PartialFunction[Any, Unit] = {
case RequestExecutors(requestedTotal) =>
Option(allocator) match {
case Some(a) => a.requestTotalExecutors(requestedTotal)
case None => logWarning("Container allocator is not ready to request executors yet.")
case Some(a) =>
allocatorLock.synchronized {
if (a.requestTotalExecutors(requestedTotal)) {
allocatorLock.notifyAll()
}
}
case None =>
logWarning("Container allocator is not ready to request executors yet.")
}
context.reply(true)
......
......@@ -146,11 +146,16 @@ private[yarn] class YarnAllocator(
* Request as many executors from the ResourceManager as needed to reach the desired total. If
* the requested total is smaller than the current number of running executors, no executors will
* be killed.
*
* @return Whether the new requested total is different than the old value.
*/
def requestTotalExecutors(requestedTotal: Int): Unit = synchronized {
def requestTotalExecutors(requestedTotal: Int): Boolean = synchronized {
if (requestedTotal != targetNumExecutors) {
logInfo(s"Driver requested a total number of $requestedTotal executor(s).")
targetNumExecutors = requestedTotal
true
} else {
false
}
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment