sunchao commented on code in PR #58437:
URL: https://github.com/apache/spark/pull/58437#discussion_r3961027224


##########
core/src/main/scala/org/apache/spark/scheduler/DAGScheduler.scala:
##########
@@ -4199,7 +4200,10 @@ private[spark] class DAGScheduler(
       execId = execId,
       fileLost = fileLost,
       hostToUnregisterOutputs = workerHost,
-      maybeEpoch = None)
+      maybeEpoch = None,
+      // Executor loss (not a fetch failure): preserve shuffles whose output 
is reliably stored
+      // off-executor. Their data survives the executor, so recomputing them 
would be wasteful.
+      skipReliablyStored = true)

Review Comment:
   [P2] Keep selective executor-loss cleanup from suppressing fetch-failure 
cleanup
   
   With the global reliability flag and external shuffle service disabled, this 
call preserves reliable outputs but still records `shuffleFileLostEpoch(execId) 
= E`. If an already-running reducer then reports `FetchFailed` at epoch E, the 
strict epoch check in `removeExecutorAndUnregisterOutputs` rejects the later 
bulk cleanup, even though those reliable outputs were never removed. 
`unregisterMapOutput` removes only the named map; its epoch increment does not 
help because the bulk cleanup uses `task.epoch`.
   
   I reproduced this with two unavailable map outputs from the lost executor: 
the first failure recomputes only one partition, then the remaining stale 
output causes another stage failure. With 
`spark.stage.maxConsecutiveAttempts=2`, the job aborts; the ordinary-shuffle 
control recomputes both and succeeds. This was a synthetic scheduler-event test 
using the reviewed sources over cached build dependencies, not a remote-shuffle 
deployment.
   
   Please distinguish selective executor-loss cleanup from full fetch-failure 
cleanup in the epoch bookkeeping, and cover `ExecutorLost` followed by a 
same-epoch `FetchFailed` for a reliably stored shuffle.



##########
core/src/main/scala/org/apache/spark/shuffle/ShuffleHandle.scala:
##########
@@ -25,4 +25,12 @@ import org.apache.spark.annotation.DeveloperApi
  * @param shuffleId ID of the shuffle
  */
 @DeveloperApi
-abstract class ShuffleHandle(val shuffleId: Int) extends Serializable {}
+abstract class ShuffleHandle(val shuffleId: Int) extends Serializable {
+  /**
+   * Whether this shuffle's output is stored reliably outside the executors 
that produced it (e.g.
+   * a remote shuffle service). When true, losing an executor does not lose 
this shuffle's output,
+   * so its map outputs are not unregistered on executor loss. Defaults to 
false; a ShuffleManager

Review Comment:
   Please make the host-loss requirement explicit in this contract. 
`DAGScheduler.handleWorkerRemoved` and the worker-host executor-loss path also 
preserve outputs when this flag is true, but the documentation currently 
promises only survival of executor loss. Storage in another process on the same 
host can meet that wording while disappearing with the worker/host. Require 
storage independent of the executor host's lifecycle, matching the existing 
`ShuffleDriverComponents.supportsReliableStorage()` contract.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to