Yang Jie created SPARK-58857:
--------------------------------

             Summary: LocalDirsFeatureStep discards the result of 
Utils.randomize, so configured local dirs are never shuffled
                 Key: SPARK-58857
                 URL: https://issues.apache.org/jira/browse/SPARK-58857
             Project: Spark
          Issue Type: Bug
          Components: Kubernetes
    Affects Versions: 5.0.0
            Reporter: Yang Jie


`LocalDirsFeatureStep.configurePod` calls `Utils.randomize` on the local dirs 
resolved from configuration but discards the result, so that branch never 
randomizes.

{code}
val resolvedLocalDirs = Option(conf.sparkConf.getenv("SPARK_LOCAL_DIRS"))
  .orElse(conf.getOption("spark.local.dir"))
  .getOrElse(defaultLocalDir)
  .split(",")
randomize(resolvedLocalDirs)                      // result dropped
localDirs = resolvedLocalDirs.toImmutableArraySeq  // original order
{code}

`Utils.randomize[T](seq: IterableOnce[T]): Seq[T]` is 
`randomizeInPlace(seq.iterator.toArray).toImmutableArraySeq` - it shuffles a 
fresh copy and returns it, so the caller observes no change to the argument. 
The in-place variant is `Utils.randomizeInPlace`. The sibling call fifteen 
lines earlier, for the pod-template branch, binds the result correctly:

{code}
var localDirs = randomize(pod.container.getVolumeMounts.asScala
  .filter(_.getName.startsWith("spark-local-dir-"))
  .map(_.getMountPath))
{code}

Both calls arrived in the same commit, 9f9af2a7bf6 (SPARK-39755, "Improve 
LocalDirsFeatureStep to randomize local directories"). An earlier revision of 
that PR used `randomizeInPlace`; review suggested `Utils.randomize` instead, 
and the next revision adopted it at both sites, binding the result at one and 
dropping it at the other. During that review a committer twice noted the test 
did not fail as expected, which is the symptom of this bug, but the discrepancy 
was attributed to force-pushes and the assertions were loosened to accept 
either order.

So `SPARK_LOCAL_DIRS`, the emptyDir volume list, and the `spark-local-dir-N` to 
path pairing are emitted in configured order, identically for every driver and 
executor pod in an application.

Scope of the observable effect, so this is not oversold: no measurable I/O or 
capacity skew follows. `DiskBlockManager.getFile` picks a directory by 
`nonNegativeHash(filename) % localDirs.length`, which spreads files 
near-uniformly within each executor regardless of the order it receives, and in 
this branch every path is backed by an emptyDir volume this step creates, so 
all of them share one node filesystem (or RAM under 
`spark.kubernetes.local.dirs.tmpfs`). What is real is that the randomization 
SPARK-39755 added, and its JIRA and release note describe, does not happen on 
this branch, and the suite's `// SPARK-39755 : Changes the method to test 
randomization` comment describes behavior that never occurs.

Fix: bind the result, matching the sibling call. Deleting the call as dead code 
is a defensible alternative if the randomization is not considered worth having.




--
This message was sent by Atlassian Jira
(v8.20.10#820010)

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

Reply via email to