@@ -30,7 +30,7 @@ import org.apache.spark.util.ActorLogReceive
3030/**
3131 * A heartbeat from executors to the driver. This is a shared message used by several internal
3232 * components to convey liveness or execution information for in-progress tasks. It will also
33- * expire the hosts that have not heartbeated for more than spark.driver.executorTimeoutMs .
33+ * expire the hosts that have not heartbeated for more than spark.network.timeoutMs .
3434 */
3535private [spark] case class Heartbeat (
3636 executorId : String ,
@@ -47,15 +47,16 @@ private[spark] case class HeartbeatResponse(reregisterBlockManager: Boolean)
4747private [spark] class HeartbeatReceiver (sc : SparkContext , scheduler : TaskScheduler )
4848 extends Actor with ActorLogReceive with Logging {
4949
50- val executorLastSeen = new mutable.HashMap [String , Long ]
50+ // executor ID -> timestamp of when the last heartbeat from this executor was received
51+ private val executorLastSeen = new mutable.HashMap [String , Long ]
5152
52- val executorTimeout = sc.conf.getLong(" spark.driver.executorTimeoutMs " ,
53+ private val executorTimeout = sc.conf.getLong(" spark.network.timeoutMs " ,
5354 sc.conf.getLong(" spark.storage.blockManagerSlaveTimeoutMs" , 120 * 1000 ))
5455
55- val checkTimeoutInterval = sc.conf.getLong(" spark.driver.executorTimeoutIntervalMs " ,
56+ private val checkTimeoutInterval = sc.conf.getLong(" spark.network.timeoutIntervalMs " ,
5657 sc.conf.getLong(" spark.storage.blockManagerTimeoutIntervalMs" , 60000 ))
5758
58- var timeoutCheckingTask : Cancellable = null
59+ private var timeoutCheckingTask : Cancellable = null
5960
6061 override def preStart (): Unit = {
6162 import context .dispatcher
@@ -66,8 +67,9 @@ private[spark] class HeartbeatReceiver(sc: SparkContext, scheduler: TaskSchedule
6667
6768 override def receiveWithLogging = {
6869 case Heartbeat (executorId, taskMetrics, blockManagerId) =>
69- val response = HeartbeatResponse (
70- ! scheduler.executorHeartbeatReceived(executorId, taskMetrics, blockManagerId))
70+ val unknownExecutor = ! scheduler.executorHeartbeatReceived(
71+ executorId, taskMetrics, blockManagerId)
72+ val response = HeartbeatResponse (reregisterBlockManager = unknownExecutor)
7173 executorLastSeen(executorId) = System .currentTimeMillis()
7274 sender ! response
7375 case ExpireDeadHosts =>
@@ -77,13 +79,13 @@ private[spark] class HeartbeatReceiver(sc: SparkContext, scheduler: TaskSchedule
7779 private def expireDeadHosts (): Unit = {
7880 logTrace(" Checking for hosts with no recent heartbeats in HeartbeatReceiver." )
7981 val now = System .currentTimeMillis()
80- val minSeenTime = now - executorTimeout
8182 for ((executorId, lastSeenMs) <- executorLastSeen) {
82- if (lastSeenMs < minSeenTime ) {
83+ if (now - lastSeenMs > executorTimeout ) {
8384 logWarning(s " Removing executor $executorId with no recent heartbeats: " +
8485 s " ${now - lastSeenMs} ms exceeds timeout $executorTimeout ms " )
85- scheduler.executorLost(executorId, SlaveLost ())
86- if (sc.supportKillExecutor) {
86+ scheduler.executorLost(executorId, SlaveLost (" Executor heartbeat " +
87+ " timed out after ${now - lastSeenMs} ms" ))
88+ if (sc.supportDynamicAllocation) {
8789 sc.killExecutor(executorId)
8890 }
8991 executorLastSeen.remove(executorId)
0 commit comments