Skip to content

[K8S][CORE] Heartbeat-timeout executor replacement may be classified as ExecutorKilled and skip task failure counting #57494

Description

@lan1994

Version
spark 3.5+ (k8s)

Description
I observed a behavior difference between Spark on Kubernetes and YARN for executor heartbeat-timeout scenarios.
In heartbeat timeout handling, HeartbeatReceiver triggers both:

  1. sc.killAndReplaceExecutor(executorId) (which uses countFailures=true)
  2. RemoveExecutor(executorId, ExecutorProcessLost(timeout))
    However, in Kubernetes backend, doKillExecutors() historically removes executors eagerly with ExecutorKilled.
    This can win the race against the later timeout-based RemoveExecutor(...ExecutorProcessLost...), so the final loss reason becomes ExecutorKilled.
    Since ExecutorKilled is treated as non-app-caused failure (exitCausedByApp=false), task failures may not be counted towards spark.task.maxFailures, and fast-fail is less likely to happen.

On k8s, heartbeat timeouts can lead to repeated task retries without triggering fast-fail.

Image

On yarn,the same task reaches the retry limit (4 attempts) and the application fails fast.

Image

Impact

  1. Heartbeat-timeout task failures may bypass failure counting.
  2. Jobs can retry for a long time instead of fast-failing.
  3. Behavior diverges from YARN under similar failure conditions.

Suggested fix direction
In K8s doKillExecutors, preserve countFailures semantics from killExecutors:
Keep ExecutorKilled for explicit driver-initiated non-counting kills.
For replacement kills (countFailures=true), avoid eagerly converting to ExecutorKilled; keep a non-ExecutorKilled reason (or allow timeout reason to land) so task-failure counting semantics are preserved.
If this direction is acceptable to maintainers, I can contribute a PR with a minimal fix and corresponding unit tests.

Additional question:
Could maintainers advise how to obtain an Apache JIRA account for new contributors?

Image

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions