[
https://issues.apache.org/jira/browse/SPARK-59094?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Chao Sun resolved SPARK-59094.
------------------------------
Fix Version/s: 4.4.0
5.0.0
Resolution: Fixed
Issue resolved by pull request 58402
[https://github.com/apache/spark/pull/58402]
> Ignore late successes from invalidated barrier shuffle attempts
> ---------------------------------------------------------------
>
> Key: SPARK-59094
> URL: https://issues.apache.org/jira/browse/SPARK-59094
> Project: Spark
> Issue Type: Bug
> Components: Spark Core
> Affects Versions: 5.0.0
> Reporter: Chao Sun
> Assignee: Chao Sun
> Priority: Major
> Labels: pull-request-available
> Fix For: 4.4.0, 5.0.0
>
>
> A deterministic barrier shuffle stage can accept a late successful task
> result after failure recovery has invalidated the entire stage attempt. The
> old result can remove a participant from the replacement barrier stage or
> mark a replacement partition complete before it launches.
> The [barrier execution
> contract|https://spark.apache.org/docs/latest/api/java/org/apache/spark/rdd/RDD.html#barrier()]
> requires all tasks in a barrier stage to be relaunched when one task fails.
> Deterministic output does not make it safe to omit one of those participants.
> Upstream draft PR:
> [apache/spark#58402|https://github.com/apache/spark/pull/58402].
> h3. Reproduction ordering
> # Run a deterministic two-partition {{RDD.barrier().mapPartitions(...)}}
> followed by a normal shuffle and {{collect()}}, using {{SortShuffleManager}}.
> Both tasks call {{BarrierTaskContext.barrier()}}. Let partition 0 finish its
> shuffle output, but delay delivery of its successful completion to the driver.
> # Fail partition 1 once. Spark fails the barrier stage and unregisters all of
> its map outputs so that both partitions should run in the next attempt.
> # Deliver partition 0's old success either before resubmission, or after the
> replacement task set is submitted but before its tasks launch.
> A native local-mode reproducer uses an executor plugin's {{onTaskSucceeded}}
> hook to hold only the completed task's success delivery. The peer failure,
> scheduler recovery, shuffle files, and downstream read use normal Spark
> execution; no constructed map statuses or scheduler-state writes are used.
> For the second ordering, an unrelated one-task job temporarily occupies one
> of the two execution slots.
> h3. Reproduction results
> Reproduced on a fresh public Spark {{5.0.0-SNAPSHOT}} build at upstream
> commit {{024120dc960517021a887b51865220f544340362}}, using Scala {{2.13.18}}.
> The native runs used Java {{21.0.12}} and {{SortShuffleManager}}; the RDD
> reports {{DETERMINATE}} output. The probe configures a three-second barrier
> timeout.
> || Delivery ordering || Unpatched behavior ||
> | After failure, before resubmission | The two-task attempt is retried with
> only one task, whose context still expects two participants. Barrier
> synchronization times out. A two-attempt limit aborts the job; a four-attempt
> limit allows an additional complete retry and successful readback. |
> | After resubmission, with one slot temporarily occupied | The replacement
> has {{successful=[true,false]}} and no running tasks. It does not launch
> after the slot is released and before the 20-second job watchdog explicitly
> cancels it. |
> The watchdog deadline is measured from the main job's start, not from slot
> release; the latter precedes cancellation by about 17 seconds in this run.
> This is a bounded stall followed by probe cancellation, not an observed
> permanent hang or a Spark-triggered abort.
> Late success after resubmission without deliberately blocked slots, a
> no-delay barrier control, and an ordinary non-barrier control all succeed.
> The unblocked case releases success on stage submission; it does not force
> delivery to wait until both replacement tasks have launched.
> With [candidate fix
> daef30b0e585|https://github.com/sunchao/spark/commit/daef30b0e585c80786c2cc1f9304ce81204a190f],
> all six matched native scenarios succeed and assert {{Seq((0, 0), (1, 1))}}.
> Every barrier retry contains both tasks; the blocked case retains
> {{successful=[false,false]}} until both tasks launch after slot release. All
> completed scenarios satisfy their probe preconditions.
> Separately, direct ScalaTest runs on JDK 17 give six new regression failures
> and 225 passes in the unpatched {{DAGSchedulerSuite}}, then 352 passes across
> the patched {{DAGSchedulerSuite}} and {{TaskSchedulerImplSuite}}. This
> validates the tested development snapshot, not a released version or a
> backport.
> h3. Cause and proposed scope
> In [DAGScheduler at upstream commit
> 024120dc960517021a887b51865220f544340362|https://github.com/apache/spark/blob/024120dc960517021a887b51865220f544340362/core/src/main/scala/org/apache/spark/scheduler/DAGScheduler.scala#L3334],
> accepted old successes can notify the task scheduler that a partition is
> complete and register its map output. A barrier task failure, including a
> fetch failure within a barrier shuffle stage, clears that failed stage's
> outputs without marking the invalidated attempt's results to be ignored.
> Before resubmission, a late registration changes the missing-partition set;
> after resubmission, the completion notification can suppress a required
> participant.
> The proposed change is limited to the two paths that clear the outputs of a
> barrier shuffle stage that has itself failed:
> * An ordinary barrier task failure.
> * A fetch failure within that barrier shuffle stage.
> Use the existing stage-attempt rollback marker to invalidate successful
> completions from that failed attempt, including the interval before a new
> attempt exists. Preserve valid replacement-attempt results and Spark's
> existing reuse of old deterministic results for ordinary non-barrier stages.
> Do not change the separate upstream barrier-producer invalidation path: a
> fetch failure reported by a downstream consumer must not invalidate an
> already-running retry of its barrier producer merely because that producer's
> outputs are cleared.
> This is related to
> [SPARK-45182|https://issues.apache.org/jira/browse/SPARK-45182],
> [SPARK-54556|https://issues.apache.org/jira/browse/SPARK-54556], and
> [SPARK-54956|https://issues.apache.org/jira/browse/SPARK-54956], which
> address old results during indeterminate or checksum-driven rollback.
> [SPARK-25161|https://issues.apache.org/jira/browse/SPARK-25161] covers
> barrier failure handling, including old failure events. This report concerns
> successful completions from a deterministic barrier attempt that has been
> invalidated.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]