-
Notifications
You must be signed in to change notification settings - Fork 29.4k
[SPARK-59332][CORE] Scope standalone shuffle service local dirs #58619
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -622,7 +622,17 @@ private[deploy] class Worker( | |
| val localRootDirs = Utils.getOrCreateLocalRootDirs(conf) | ||
| val dirs = localRootDirs.flatMap { dir => | ||
| try { | ||
| val appDir = Utils.createDirectory(dir, namePrefix = "executor") | ||
| // Nest executor local dirs under a per-application directory (the app id as | ||
| // a path segment) so the external shuffle service can require registered | ||
| // localDirs to be scoped to the registering application. | ||
| val appIdDir = new File(dir, appId) | ||
| appIdDir.mkdirs() | ||
| if (!appIdDir.isDirectory) { | ||
| throw new IOException(s"Failed to create directory $appIdDir") | ||
| } | ||
| Utils.chmod700(appIdDir) | ||
| val appDir = Utils.createDirectory(appIdDir.getAbsolutePath(), | ||
| namePrefix = "executor") | ||
| Utils.chmod700(appDir) | ||
| Some(appDir.getAbsolutePath()) | ||
|
Comment on lines
+625
to
637
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This additional Since val appDir = new File(dir, appId)
if (!Utils.createDirectory(appDir)) {
throw new IOException(s"Failed to create directory $appDir")
}
Utils.chmod700(appDir)
Some(appDir.getAbsolutePath())One caveat: in If we keep the current layout, please use |
||
| } catch { | ||
|
|
@@ -777,6 +787,15 @@ private[deploy] class Worker( | |
| logInfo(log"Cleaning up local directories for application ${MDC(APP_ID, id)}") | ||
| dirList.foreach { dir => | ||
| Utils.deleteRecursively(new File(dir)) | ||
| // Executor dirs are nested under a per-application directory; remove it too | ||
| // once it is empty. | ||
| val appIdDir = new File(dir).getParentFile | ||
| if (appIdDir != null && appIdDir.getName == id) { | ||
| val remaining = appIdDir.list() | ||
| if (remaining != null && remaining.isEmpty) { | ||
| appIdDir.delete() | ||
| } | ||
| } | ||
| } | ||
| }(cleanupThreadExecutor).failed.foreach(e => | ||
| logError(log"Clean up app dir ${MDC(PATHS, dirList)} failed", e) | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
|
|
@@ -908,6 +908,22 @@ package object config { | |||||||
| .stringConf | ||||||||
| .createWithDefault("spark_shuffle") | ||||||||
|
|
||||||||
| private[spark] val SHUFFLE_SERVICE_REQUIRE_APP_SCOPED_LOCAL_DIRS = | ||||||||
| ConfigBuilder("spark.shuffle.service.requireAppScopedLocalDirs") | ||||||||
| .doc("Whether the external shuffle service requires every local directory an executor " + | ||||||||
| "reports at registration to lie inside the registering application's own " + | ||||||||
| "per-application directory: the application id must appear as a path segment of the " + | ||||||||
| "directory's canonical path, under one of the service's configured local directory " + | ||||||||
| "roots. This keeps each application's shuffle and RDD blocks within its own directory " + | ||||||||
| "scope at registration and cleanup time. Only affects standalone mode. Enable it only " + | ||||||||
|
Comment on lines
+917
to
+918
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In standalone mode, the shuffle service authenticates all applications with a single shared secret ( This config helps to prevent mis-registration (e.g., bugs or races), but it doesn't isolate applications from a malicious one. Could you revise this sentence (and the same one in |
||||||||
| "after every Worker in the cluster creates executor local directories under a " + | ||||||||
| "per-application directory (Workers on this version do); executors launched by older " + | ||||||||
| "Workers report unscoped paths and their registrations are rejected while this is " + | ||||||||
| "enabled.") | ||||||||
| .version("4.4.0") | ||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. New configs are required to declare a binding policy and the exception file is frozen. This is the cause of
Suggested change
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 4.3.0? |
||||||||
| .booleanConf | ||||||||
| .createWithDefault(false) | ||||||||
|
|
||||||||
| private[spark] val KEYTAB = ConfigBuilder("spark.kerberos.keytab") | ||||||||
| .doc("Location of user's keytab.") | ||||||||
| .version("3.0.0") | ||||||||
|
|
||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The rollout unit is the Worker, not the application: the config doc and
docs/spark-standalone.mdboth say to upgrade every Worker first, and the sentence just above already attributes the per-app layout to Workers.